2017-10-07 103 views
0

當從父項分離的子進程死亡後,它仍然存在一定程度並保持殭屍狀態,直到它從wait()調用中獲得。從父項分離子進程

是可以分離這種親子關係,並讓孩子自動收割?也許孤兒關小孩初始化,或者什麼?

可能的使用案例:在一個長壽命的程序中創建大量的「即燃即用」進程,而不會「持有」越來越多的無法被操作系統回收的殭屍PID。

回答

1

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