我从主控主机到从属主机执行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