在Linux / C ++库中,我通过system()调用
启动一个进程system("nohup processName > /dev/null&");
这似乎与一个简单的测试应用程序可以正常工作,但是如果我从Nodejs / V8扩展中获取一个kill信号,那么子进程就会被杀死。我确实找到了跑步,
system("sudo nohup processName > /dev/null&");
将sudoers文件设置为不需要密码即使在父进程(节点)退出时也设置为运行。有没有办法完全分离儿童过程,所以发送给父母和父母的信号不再对孩子有影响?最好是在system()调用中,而不是需要获取进程ID并使用它做某事的东西。
答案 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
并使用fork
和execve
或posix_spawn
。