fork + exec + caller 不应该等待孩子
Posted
技术标签:
【中文标题】fork + exec + caller 不应该等待孩子【英文标题】:fork + exec + caller should not wait for child 【发布时间】:2012-05-22 08:04:52 【问题描述】:我有两个脚本 script_a 和 script_b。 script_a 调用 script_b。 script_b 分叉两个进程。如下图。
script_a 等待 script_b 的父级和子级都完成。 我希望 script_a 继续运行而不等待 script_b 的子进程。
为此我所做的是在script_b中,我添加了以下代码。
if (! $f_id)
close STDOUT;
close STDERR;
exec("sleep 10; echo 'i am child'");
这对我有用。 script_a 不再等待子进程。
我的问题是, 1. 这是正确的方法吗? 2. 父进程和子进程是否共享相同的 STDOUT 和 STDERR,如果存在竞争条件,我最终会遇到麻烦吗? 3. 有更好的方法吗?
提前感谢您的帮助。
script_a.pl
#! /usr/local/bin/perl
print `script_b.pl`;
script_b.pl
#! /usr/local/bin/perl
$f_id = fork();
if (! $f_id)
exec("sleep 10; echo 'i am child'");
if ($f_id)
print "i am parent\n";
【问题讨论】:
1) 您可能只是在 script_a 上分叉,但不知道您的真正问题很难说。 2) 反引号操作符只是为孩子设置了一个新的 STDOUT。 STDERR 是共享的。 @Salva 这是我实际代码的缩小版本,所以看起来我可以只在 script_a 上分叉,但在真正的场景中它不是我的选择。 script_b 中的父子节点会共享相同的 STDOUT 和 STDERR 吗? STDOUT/STDERR 未共享。从创建子节点开始,所有描述符都从父节点继承。一旦分叉,它们就可以被独立操作。 script_a 和 script_b 需要通信吗?您的样本表明 A 想要 B 的输出,但那是真实程序的代表吗?为什么 script_a 中没有fork
选项?
@GregBacon 从一个虚拟脚本 (script_a) 我启动我的实际命令 (script_b) 捕获其退出状态并根据退出状态发送邮件。作为其执行的一部分,这个实际的命令分叉。但我只是对父母的返回值感兴趣,不想等待孩子完成。
【参考方案1】:
而不是在 script_a 中使用 ``。我们已经重定向了 script_a 中的 STDOUT 和 STDERR。 类似的东西
script_a
system("script_b.pl > /var/tmp/out_file 2>&1");
脚本_b
#! /usr/local/bin/perl
$f_id = fork();
if (! $f_id)
exec("sleep 10; echo 'i am child'");
if ($f_id)
print "i am parent\n";
这样调用者不会等待 exec 中的子进程完成。
在这里感谢您的帮助。
【讨论】:
【参考方案2】: perl 中的`` 反引号 等待命令完成。因此,如果您不希望父进程等待,请在后台放入 sytem(command &)。
【讨论】:
我想等家长回来。但我不想等孩子。如果我提出的解决方案有任何问题,您能告诉我吗?以上是关于fork + exec + caller 不应该等待孩子的主要内容,如果未能解决你的问题,请参考以下文章