使用system()生成的子进程在父获取kill信号并退出后继续运行

时间:2012-10-17 23:52:58

标签: c++ c linux node.js process

在Linux / C ++库中,我通过system()调用

启动一个进程
system("nohup processName > /dev/null&");

这似乎与一个简单的测试应用程序可以正常工作,但是如果我从Nodejs / V8扩展中获取一个kill信号,那么子进程就会被杀死。我确实找到了跑步,

system("sudo nohup processName > /dev/null&");

将sudoers文件设置为不需要密码即使在父进程(节点)退出时也设置为运行。有没有办法完全分离儿童过程,所以发送给父母和父母的信号不再对孩子有影响?最好是在system()调用中,而不是需要获取进程ID并使用它做某事的东西。

2 个答案:

答案 0 :(得分:4)

从父进程分离的过程很简单:在setsid下运行命令(因此它在新会话中启动),将标准输入,输出和错误重定向到/dev/null(或其他地方) (视情况而定),在子壳的背景中。因为system()启动了一个新shell,它等同于这样一个子shell,所以

system("setsid COMMAND </dev/null >/dev/null 2>/dev/null &");

完全满足需要。在shell脚本中,等效的是

( setsid COMMAND </dev/null >/dev/null 2>/dev/null & )

(Shell脚本需要一个子shell,因为否则COMMAND将在当前shell的作业控制之下。这在使用system()时并不重要,因为它只为命令启动一个新的shell无论如何;当命令退出时,shell将退出。)

重定向是确保COMMAND没有当前终端的开放描述符所必需的。 (当终端关闭时,TERM信号被发送到所有这些进程。)这意味着必须重定向标准输入,标准输出和标准错误。上述重定向在Bash和POSIX shell中都有效,但在古代版本的/bin/sh中可能不起作用。特别是它应该适用于所有Linux发行版。

setsid开始一个新会话; COMMAND成为其自己的流程组的流程组负责人。信号可以指向单个进程,也可以指向进程组中的所有进程。终止信号通常发送到整个进程组(因为应用程序在技术上可能包含多个相关进程)。如果父进程所属的进程组被进程组范围的信号终止,则启动新会话可确保COMMAND不会被杀死。

答案 1 :(得分:2)

我的猜测是整个过程组都被杀死了。您可以在子项中尝试setpgid来启动新的流程组。第一步应该是摆脱system并使用forkexecveposix_spawn