我有一個子進程,只是exit(0)
。它變成了殭屍。在父進程中沒有wait
或waitpid
,有沒有辦法刪除它?殭屍進程刪除無需等待C
R+ ./server //parent
R+ ./server //child
Z+ (server) //child zombie
我有一個子進程,只是exit(0)
。它變成了殭屍。在父進程中沒有wait
或waitpid
,有沒有辦法刪除它?殭屍進程刪除無需等待C
R+ ./server //parent
R+ ./server //child
Z+ (server) //child zombie
最簡單的就是讓SIGCHLD父忽略:
signal(SIGCHLD, SIG_IGN);
之後,退出子進程將只是乾淨走開,而無需進行等待上。
注意:這是一個快速的&髒方法,並且假定您根本不在乎子進程的退出狀態,或者關於它何時退出。如果你真的關心,你可能應該在一個真正強大的應用程序中,然後看看另一個答案,關於創建一個合適的信號處理函數。
此外:這在Unix中不是通用的,但至少在Linux上起作用。根據an UNIX FAQ,它在POSIX中是未定義的行爲。例如,This Mac OS X man page表明此行爲是在FreeBSD 5.0中引入的,並且適用於OS X。
僅當父進程退出時,子進程不會消失(不是殭屍)嗎?換句話說,他們不是殭屍,直到父母退出?我可以想象,即使忽略了'SIGCHLD'信號,父類仍然可以'waitpid',因此內核必須對子進程進行zombify(但我可能是錯的,因爲我沒有測試它)。 – 2013-05-03 17:52:20
@BasileStarynkevitch增加了一段和解釋更多的鏈接。但是當它工作時,然後退出/終止的子進程真的會消失,沒有殭屍,無法等待。 – hyde 2013-05-05 06:18:16
但子進程立即消失,還是僅在父進程退出? – 2013-05-05 12:24:02
你可以趕上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。它有很好的流程章節。
您可以使用雙fork
技術:
創建一個子子進程。之後立即終止子進程。 通過這種方式,子孩子進程將在init
進程下進行。當子進程退出時,init
進程將自動等待。
這不會刪除waitpid
,因爲父級必須等待子進程結束。 由於子進程的生命週期總是最短,因此您可以從父進程調用waitpid
而不會阻塞。
查看this article瞭解更多信息。
不知道這是一個C的帖子。也許是因爲Unix是用C創建的? :) – 2013-05-03 17:00:52
爲什麼你不想使用'wait'或'waitpid'? – FDinoff 2013-05-03 17:01:24
,因爲'wait'會停止父進程,直到子進程退出。 – 2013-05-03 17:02:37