与父进程分离子进程

Sha*_*ggi 5 unix posix child-process

当从父进程派生的子进程死亡时,它在某种程度上仍然存在并处于僵尸状态,直到从wait()调用中获得该进程为止。

是否可以解除这种亲子关系并让孩子自动获得收成?也许让孩子成为孩子的孤儿,或者其他什么?

可能的用例:在一个长期存在的程序中创建许多“抛弃式”进程,而无需“保留”越来越多的无法由OS回收的僵尸PID。

And*_*nle 5

根据POSIX _exit()文档

如果调用进程的父进程已设置其 SA_NOCLDWAIT标志或已将SIGCHLD信号的操作设置为 SIG_IGN

  • 流程的状态信息(请参阅状态信息)(如果有的话)应被丢弃。

  • 调用过程的生存期应立即结束。如果SA_NOCLDWAIT设置为,则实现定义是否将SIGCHLD 信号发送到父进程。

  • 如果调用进程的父进程中的线程被阻塞的wait()waitpid()waitid()在设定的等待,对于孩子来说,与父进程已经没有剩余的子进程 wait()waitid()waitpid()功能失败,将设置errno 为[ ECHILD]。

除此以外:

  • 状态信息(请参阅状态信息)将生成。

  • 调用过程应转变为僵尸过程。其状态信息应提供给父流程,直到流程的生命周期结束为止。

  • ...

简而言之,为了防止子进程成为僵尸进程,最简单的方法是调用 sigignore( SIGCHLD );

更新

这确实影响了等待任何子进程的能力,这可能是不希望的。该setsid()库函数允许进程从其父撇清自己:

pid_t child = fork();
if ( ( pid_t ) 0 == child )
{
    int rc = setsid();

    rc = execv(...);
}
else ...
Run Code Online (Sandbox Code Playgroud)

SIGCHLD在我安装的Solaris 11.2实例上,未关联的子进程既不会创建僵尸,也不会发送给父进程。

这是“即发即弃”子进程的简化守护进程,仅执行防止创建僵尸或发送SIGCHLD给父进程所需的操作。有关更完整的守护程序,请参阅Linux守护程序。