从父项分离子进程

问题描述:

当从父项分离的子进程死亡后,它仍然存在一定程度并保持僵尸状态,直到它从wait()调用中获得。从父项分离子进程

是可以分离这种亲子关系,并让孩子自动收割?也许孤儿关小孩初始化,或者什么?

可能的使用案例:在一个长寿命的程序中创建大量的“即燃即用”进程,而不会“持有”越来越多的无法被操作系统回收的僵尸PID。

the POSIX _exit() documentation

如果调用进程的父进程中树立了 SA_NOCLDWAIT标志或已设置为SIGCHLD信号的动作 SIG_IGN

  • 的过程状态信息(见状态信息),如果有的话,应该被丢弃。

  • 调用进程的生命周期应立即终止。如果设置了SA_NOCLDWAIT,则执行定义是否将SIGCHLD 信号发送给父进程。

  • 如果调用进程的父进程中的线程被阻塞在wait()waitpid(),或waitid(),并父进程具有 在一套没有剩余的子进程等待,对于儿童来说, wait()waitid() ,或waitpid()函数将失败并将errno 设置为[ECHILD]。

否则:

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

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

  • ...

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

UPDATE

这确实影响能够等待任何子进程,这可能不是所期望的。该setsid() library function允许进程从其父撇清自己:

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

    rc = execv(...); 
} 
else ... 

脱离的子进程不会创建一个僵尸也不发送SIGCHLD父进程在我安装的Solaris 11.2的实例。

这是一种“发射后不管”子流程的简化系统守护进程,只是在做什么是必要的,以防止创建一个僵尸或发送SIGCHLD父进程。有关更完整的守护程序过程,请参见Linux daemonize

+0

谢谢,您是否知道任何不会改变程序中全局行为的解决方案?该解决方案将改变可能想要与他们的孩子同步的程序的其他未知部分。 – Shaggi

+0

@Shaggi查看更新。你应该能够在'fork()'之后和'execv *()'之前使用'setsid()'来允许子进程从父进程“隐藏”,而不是在终止时创建一个僵尸或者发送'SIGCHLD' 。 –

+0

非常好,谢谢。我最后的愿望是能够在孩子一生的任意阶段从父母那里做到这一点,但我想这不是真的可能。 – Shaggi