使子进程生成与system()继续运行后,父获取终止信号和退出 [英] Make child process spawned with system() keep running after parent gets kill signals and exits

查看:809
本文介绍了使子进程生成与system()继续运行后,父获取终止信号和退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux / C ++库中,我通过system()调用启动一个进程,

In a Linux/C++ library I'm launching a process via the system() call,

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

这似乎可以用一个简单的测试应用程序退出它自己,但如果我使用从获得kill信号的Nodejs / V8扩展的内部,子进程被杀死。我发现正在运行

This seems to work fine with a simple test application that exits on it's own, but if I use this from inside of a Nodejs/V8 extension which gets a kill signal, the child process gets killed. I did find that running,

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

使用设置为不需要密码的sudoers文件即使在父进程(节点)退出。有没有某种地方完全分离子进程,所以发送给父进程和父进程退出的信号对子进程没有影响了?

With the sudoers file set up to not require a password manages to make this run even when the parent process (node) exits. Is there someway to entirely detach the child process so signals sent to the parent and the parent exiting have no effect on the child anymore? Preferably within the system() call and not something that requires getting the process ID and doing something with it.

推荐答案

在程序中,从父进程分离很简单:在 setsid 下运行命令(因此它在新会话中启动),将标准输入,输出和错误重定向到 / dev / null (或适当的其他地方)。因为 system()启动一个新的shell,所以它等效于这样一个subshel​​l,因此

The procedure to detach from the parent process is simple: Run the command under setsid (so it starts in a new session), redirecting standard input, output and error to /dev/null (or somewhere else, as appropriate), in background of a subshell. Because system() starts a new shell, it is equivalent to such a subshell, so

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

完全符合需要。在shell脚本中,等价的是

does exactly what is needed. In a shell script, the equivalent is

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

(Shell脚本需要一个subshel​​l,否则 COMMAND 将在当前shell的作业控制之下,这在使用 system()时并不重要,因为它启动一个新的shell

(Shell scripts need a subshell, because otherwise the COMMAND would be under job control for the current shell. That is not important when using system(), because it starts a new shell just for the command anyway; the shell will exit when the command exits.)

重定向是必要的,以确保 COMMAND 对当前终端没有打开的描述符。 (当终端关闭时,TERM信号被发送到所有这样的进程。)这意味着标准输入,标准输出和标准错误都必须重定向。以上重定向在Bash和POSIX shell中都有效,但在 / bin / sh 的旧版本中可能无法正常工作。

The redirections are necessary to make sure the COMMAND has no open descriptors to the current terminal. (When the terminal closes, a TERM signal is sent to all such processes.) This means standard input, standard output, and standard error all must be redirected. The above redirections work in both Bash and POSIX shells, but might not work in ancient versions of /bin/sh. In particular, it should work in all Linux distros.

setsid 开始一个新的会话; COMMAND 成为其自己的进程组的进程组组长。可以将信号定向到单个进程,或者定向到进程组中的所有进程。终止信号通常被发送到整个过程组(因为应用在技术上可以由多个相关过程组成)。启动新会话可确保如果父进程所属的进程组由进程组宽信号终止, COMMAND 不会被终止。

setsid starts a new session; the COMMAND becoming the process group leader for its own process group. Signals can be directed to either a single process, or to all processes in a process group. Termination signals are usually sent to entire process groups (since an application may technically consist of multiple related processes). Starting a new session makes sure COMMAND does not get killed if the process group the parent proces belongs to is killed by a process-group wide signal.

这篇关于使子进程生成与system()继续运行后,父获取终止信号和退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆