gpt4 book ai didi

linux - 如何避免 进程?

转载 作者:可可西里 更新时间:2023-11-01 11:51:54 26 4
gpt4 key购买 nike

我执行从主控主机到从属主机的 ZFS 远程复制,其中我有一个在主控主机上运行的 Perl 脚本。

对于每个文件系统,它通过 ssh 连接到远程主机并以监听模式启动 mbuffer,然后脚本继续执行并发送数据。成功时 mbuffer 应该自行退出。

问题

通过 ssh 在远程主机上启动 mbuffer 然后能够在脚本中继续是相当困难的。我最终做了你在下面看到的事情。

问题是在脚本退出之前它会留下 <defunct>为每个文件系统处理一个。

问题

可以避免 <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 收割它的子进程。或 waitpid .它还可以导致其子项在创建子项之前通过使用 local $SIG{CHLD} = 'IGNORE'; 自动收割。


请注意,Parallel::ForkManager 不是启动单个子项的正确工具。产生单个 worker 不是它的目的。

use String::ShellQuote qw( shell_quote );

sub mbuffer {
my ($id, $zfsPath) = @_;

my $mbuffer_cmd = shell_quote($mbuffer, '-I', $::c{port});
my $zfs_cmd = shell_quote($zfs, 'receive', $zfsPath);
my $remote_cmd = "$mbuffer_cmd | $zfs_cmd";
my $local_cmd = shell_quote($ssh, $::c{slaves}{$id}, $remote_cmd);

# open3 will close this handle.
# open3 doesn't deal well with lexical handles.
open(local *CHILD_STDIN, '<', '/dev/null') or die $!;

return open3('<&CHILD_STDIN', '>&STDOUT', '>&STDERR', $local_cmd);
}

IPC::Open3 级别很低,但它最接近您现有的代码。启动进程的更好方法包括 IPC::Run3 和 IPC::Run。

关于linux - 如何避免 <defunct> 进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45591907/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com