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_ascript_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 不应该等待孩子的主要内容,如果未能解决你的问题,请参考以下文章

fork,wait和exec

fork,wait和exec

PHP中的异步shell exec

linux中fork, source和exec的区别

Linux C fork exec介绍用法

Linux下进程的创建(system(); fork(); exec*())