我有一個Perl腳本,它分叉了許多子進程。我想要有一些功能,如xargs --max-procs=4 --max-args=1
或make -j 4
,其中Perl將保持運行的給定數量的進程,直到它失去工作。perl進程隊列
很容易說fork四個進程並等待它們全部完成,然後再fork另外四個進程,但是我希望同時運行四個或n個進程,只要一個完成。
在Perl中有一種簡單的方法來實現這樣的進程池嗎?
我有一個Perl腳本,它分叉了許多子進程。我想要有一些功能,如xargs --max-procs=4 --max-args=1
或make -j 4
,其中Perl將保持運行的給定數量的進程,直到它失去工作。perl進程隊列
很容易說fork四個進程並等待它們全部完成,然後再fork另外四個進程,但是我希望同時運行四個或n個進程,只要一個完成。
在Perl中有一種簡單的方法來實現這樣的進程池嗎?
Forks::Super
可以處理這個要求。
呼叫至fork()
可以阻塞,直到活性子進程的數量低於5,也可以通過額外的參數到fork
呼叫和要執行的任務可以排隊:
fork { sub => sub { ... task to run in subprocess ... } }
當一個子進程結束後,隊列中的另一項工作將啓動。
(我是本模塊的作者)。
退房Parallel::ForkManager - 它確實很多你的描述。您可以設置最大數量的進程,並且回調函數一旦完成(只要有工作要做)就可以啓動新的子進程。
雖然我幾乎總是使用CPAN模塊,或寫在夢幻般的AnyEvent模塊的東西,我認爲其重要的是瞭解這些東西的引擎蓋下是如何工作的。這裏有一個除perl之外沒有依賴關係的例子。同樣的方法也可以用C編寫而不會有太多的麻煩。
#!/usr/bin/env perl
use strict;
## run a function in a forked process
sub background (&) {
my $code = shift;
my $pid = fork;
if ($pid) {
return $pid;
} elsif ($pid == 0) {
$code->();
exit;
} else{
die "cant fork: $!"
}
}
my @work = ('sleep 30') x 8;
my %pids =();
for (1..4) {
my $w = shift @work;
my $pid = background {
exec $w;
};
$pids{$pid} = $w;
}
while (my $pid = waitpid(-1,0)) {
if ($?) {
if ($? & 127) {
warn "child died with signal " . ($? & 127);
} else {
warn "chiled exited with value " . ($? >> 8);
}
## redo work that died or got killed
my $npid = background {
exec $pids{$pid};
};
$pids{$npid} = delete $pids{$pid};
} else {
delete $pids{$pid};
## send more work if there is any
if (my $w = shift @work) {
my $pid = background {
exec shift @work;
};
$pids{$pid} = $w;
}
}
}
是什麼塊和隊列之間的區別? – srchulo 2012-11-08 22:35:58
'block'會讓你的程序等待,直到某些子進程完成,以便下一個任務可以開始。 'queue'將把當前任務放入一個隊列中,讓程序繼續運行。當其他子進程完成時,隊列中的作業將異步啓動。 – mob 2012-11-08 22:40:32
哦,好的。非常感謝! – srchulo 2012-11-08 23:44:25