2013-05-03 55 views
5

我有一個子進程,只是exit(0)。它變成了殭屍。在父進程中沒有waitwaitpid,有沒有辦法刪除它?殭屍進程刪除無需等待C

R+ ./server //parent 
R+ ./server //child 
Z+ (server) //child zombie 
+0

不知道這是一個C的帖子。也許是因爲Unix是用C創建的? :) – 2013-05-03 17:00:52

+0

爲什麼你不想使用'wait'或'waitpid'? – FDinoff 2013-05-03 17:01:24

+0

,因爲'wait'會停止父進程,直到子進程退出。 – 2013-05-03 17:02:37

回答

5

最簡單的就是讓SIGCHLD父忽略:

signal(SIGCHLD, SIG_IGN); 

之後,退出子進程將只是乾淨走開,而無需進行等待上。

注意:這是一個快速的&髒方法,並且假定您根本不在乎子進程的退出狀態,或者關於它何時退出。如果你真的關心,你可能應該在一個真正強大的應用程序中,然後看看另一個答案,關於創建一個合適的信號處理函數。

此外:這在Unix中不是通用的,但至少在Linux上起作用。根據an UNIX FAQ,它在POSIX中是未定義的行爲。例如,This Mac OS X man page表明此行爲是在FreeBSD 5.0中引入的,並且適用於OS X。

+1

僅當父進程退出時,子進程不會消失(不是殭屍)嗎?換句話說,他們不是殭屍,直到父母退出?我可以想象,即使忽略了'SIGCHLD'信號,父類仍然可以'waitpid',因此內核必須對子進程進行zombify(但我可能是錯的,因爲我沒有測試它)。 – 2013-05-03 17:52:20

+0

@BasileStarynkevitch增加了一段和解釋更多的鏈接。但是當它工作時,然後退出/終止的子進程真的會消失,沒有殭屍,無法等待。 – hyde 2013-05-05 06:18:16

+0

但子進程立即消失,還是僅在父進程退出? – 2013-05-05 12:24:02

6

你可以趕上SIGCHLD信號(例如使用sigaction(2)等)。要小心,很少的函數可以從信號處理程序安全地調用。多次閱讀signal(7) & signal-safety(7)。在信號處理器內部做的一件好事是設置一些volatile sigatomic_t標誌(稍後將測試,在信號處理器的之外,例如在某些event loop中)。或者你可以在初始化時設置一個pipe(7)(對你自己的進程),並在你的信號處理器上寫入幾個字節(poll(2)讀取結束),如suggested by Qt

而且waitpid(2)可以告訴不WNOHANG

停止如果你從來沒有等待你的子進程,它將成爲zombie

閱讀Advanced Linux Programming。它有很好的流程章節。

2

您可以使用雙fork技術:

創建一個子子進程。之後立即終止子進程。 通過這種方式,子孩子進程將在init進程下進行。當子進程退出時,init進程將自動等待。

這不會刪除waitpid,因爲父級必須等待子進程結束。 由於子進程的生命週期總是最短,因此您可以從父進程調用waitpid而不會阻塞。

查看this article瞭解更多信息。