我從主控主機到從屬主機執行ZFS遠程複製,其中我有一個在主控主機上運行的Perl腳本。如何避免<defunct>進程?
對於每個文件系統,ssh到遠程主機並在監聽模式下啓動mbuffer,然後腳本繼續併發送數據。成功時,mbuffer應該自行退出。
問題
這是相當困難的開始mbuffer通過ssh遠程主機上,然後可以繼續在腳本。我最終做了你可以在下面看到的內容。
問題是,在腳本退出之前,它會爲每個文件系統處理一個文件系統。
問題
有可能避免在<defunct>
流程?
sub mbuffer {
my ($id, $zfsPath) = @_;
my $m = join(' ', $mbuffer, '-I', $::c{port});
my $z = join(' ', $zfs, 'receive', , $zfsPath);
my $c = shellQuote($ssh, $::c{slaves}{$id}, join('|', $m, $z));
my $pm = Parallel::ForkManager->new(1);
my $pid = $pm->start;
if (!$pid) {
no warnings; # fixes "exec" not working
exec($c);
$pm->finish;
}
sleep 3; # wait for mbuffer to listen
return $pid;
}
父進程必須始終在其子進程上調用「wait」(或其一個變體),以便讓內核知道終止的子進程可以清理。 [這個問題](https://stackoverflow.com/questions/9164316/c-fork-without-wait-defuncts-execl)有一些答案,可能會指出你在正確的方向。 – Thomas
最快的解決方法是設置'$ SIG {CHLD} ='IGNORE''。見['perldoc -f fork'](http://metacpan.org/pod/perlfunc#fork) – mob
一個不存在的進程或殭屍進程是一個終止進程,沒有它的父母調用'wait'就可以了。因此,內核保留終止的子進程的條目,所以當父進程調用「wait」時,它會返回所需的信息。爲了避免殭屍,父進程需要等待其子進程。 – direprobs