与父进程分离子进程 [英] Detach child process from parent
问题描述
当从父进程派生的子进程死亡时,它在某种程度上仍然存在,并处于僵尸状态,直到从wait()调用中获得该子进程为止.
When a child process forked from a parent dies, it still exists to some extent and is left in a zombie state, until it is reaped from a wait() call.
是否可以解除这种亲子关系,并让孩子自动获得收成?也许让孩子成为孩子的孤儿,或者其他什么事情?
Is is possible to detach this parent-child relationship and have the children be automatically reaped? Maybe orphan off the child to init, or something?
可能的用例:在一个长期存在的程序中创建大量的抛弃式"进程,而无需持有"越来越多的无法由操作系统回收的僵尸PID.
Possible use case: Creating a lot of fire-and-forget processes in a long-lived program, without "holding" on to an increasing list of zombie PIDs that cannot be recycled by the OS.
推荐答案
如果调用进程的父进程已设置其
SA_NOCLDWAIT
标志或已将SIGCHLD
信号的操作设置为SIG_IGN
:
If the parent process of the calling process has set its
SA_NOCLDWAIT
flag or has set the action for theSIGCHLD
signal toSIG_IGN
:
-
该进程的状态信息(请参阅状态信息)(如果有的话)应被丢弃.
The process' status information (see Status Information), if any, shall be discarded.
调用过程的生存期将立即结束.如果设置了SA_NOCLDWAIT
,则是否定义SIGCHLD
由实现定义
信号发送到父进程.
The lifetime of the calling process shall end immediately. If SA_NOCLDWAIT
is set, it is implementation-defined whether a SIGCHLD
signal is sent to the parent process.
如果在wait()
,waitpid()
或waitid()
中阻塞了调用进程的父进程中的线程,并且父进程具有
在等待的孩子集中,没有剩余的孩子进程,
wait()
,waitid()
或waitpid()
功能将失败并设置errno
到[ECHILD
].
If a thread in the parent process of the calling process is blocked in wait()
, waitpid()
, or waitid()
, and the parent process has
no remaining child processes in the set of waited-for children, the
wait()
, waitid()
, or waitpid()
function shall fail and set errno
to [ECHILD
].
否则:
-
状态信息(请参阅状态信息)将生成.
Status information (see Status Information) shall be generated.
应将呼叫过程转换为僵尸过程.其状态信息应提供给父进程 直到进程的生命周期结束.
The calling process shall be transformed into a zombie process. Its status information shall be made available to the parent process until the process' lifetime ends.
...
简而言之,为了防止子进程成为僵尸进程,最简单的方法是调用sigignore( SIGCHLD );
In short, to prevent child processes from becoming zombie processes, the simplest way is to call sigignore( SIGCHLD );
更新
那确实影响了等待任何子进程的能力,这可能是不希望的. setsid()
库函数允许进程将自身与其父级解除关联:
That does impact the ability to wait for any child process, which may not be desired. The setsid()
library function allows a process to disassociate itself from its parent:
pid_t child = fork();
if ( ( pid_t ) 0 == child )
{
int rc = setsid();
rc = execv(...);
}
else ...
解除关联的子进程不会在我安装的Solaris 11.2实例上创建僵尸,也不会发送SIGCHLD
到父进程.
The disassociated child process doesn't create a zombie nor send SIGCHLD
to the parent process on my installed instance of Solaris 11.2.
这是即发即弃"子进程的缩写守护进程,仅执行防止创建僵尸程序或将SIGCHLD
发送给父进程的必要操作.有关更完整的守护程序,请参见 Linux守护程序
This is an abbreviated daemonization of a "fire-and-forget" child process, only doing what is necessary to prevent creating a zombie or sending SIGCHLD
to the parent process. For a much fuller daemonization procedure, see Linux daemonize
这篇关于与父进程分离子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!