如果其父级首先完成,后台进程是否完成?

时间:2017-11-02 02:26:40

标签: perl

我不确定这个问题是否特定于Perl,但它是我正在使用的语言。假设我启动后台进程以将网页保存到本地文件,如下所示:

system("curl http://google.com > output_file.html &");

我知道这会启动一个后台进程,虽然我不完全确定细节(例如它是否有自己的PID?)。但对我来说特别重要的是,如果启动它的进程在curl完成下载之前终止会发生什么?卷曲是允许继续,还是会终止?

是否有任何理由解决方案不会在nohupnohup curl ...)之前添加上述命令?见http://linux.101hacks.com/unix/nohup-command/

1 个答案:

答案 0 :(得分:3)

是的,即使脚本首先退出,您的后台进程也应该完成。

system调用fork,这意味着在此时创建一​​个新的独立进程作为父进程的近似克隆。然后,该进程将由要运行的命令替换,或由将运行该命令的shell替换。 system然后wait用于子进程完成。< / p>

命令中的&确保它是由system运行的shell,然后执行命令。 shell本身fork是一个进程(子shell),执行命令,不等待它,但立即返回。

此时system的工作已完成,并将控制权返回给脚本。

shell分叉的进程的命运与shell或脚本无关,并且进程将运行完成。 父母可能会立即退出。请参阅

use warnings;
use strict;
use feature 'say';

system("(sleep 5; echo hi) &");

say "Parent exiting.";

或者,从终端

perl -wE'system("(sleep 3; echo me)&"); say "done"'

进入shell后,()启动一个子shell,此处用于在此示例的后台放置多个命令(并表示您的命令)。通过bash internal variables $BASHPID$$$PPID(此处为$$ differs from $BASHPID

跟踪流程ID时,请注意这一点
perl -wE'say $$; system("
    ( sleep 30; echo \$BASHPID; echo \$PPID; echo \$\$ ) &
"); say "done"'

然后在我的系统上通过ps aux使用| tail -n 10来查看进程。

大多数情况下,system - 运行命令的PID将比脚本的PID大2,因为它们之间有一个shell(对于我的系统上的后台进程)。在上面的示例中,它应该大于3,因为带有多个命令的附加()子shell。

这假定/bin/sh使用的system确实被降级为bash

注意:当父母退出时,孩子会被init重新成为父母,一切都很好(没有僵尸)。

来自system

  

exec完全相同,除了首先完成fork并且父进程等待子进程退出。请注意,参数处理因参数的数量而异。如果LIST中有多个参数,或者LIST是具有多个值的数组,则使用列表其余部分给出的参数启动列表的第一个元素给出的程序。如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(在Unix平台上为/bin/sh -c,但在其他方面有所不同平台)。如果参数中没有shell元字符,则将其拆分为单词并直接传递给execvp,这样效率更高。 ...

...启动第一个元素给出的程序...... ”也意味着execvp,见exec