我有一個Tcl腳本運行進程的情況,即fork()
離開分叉進程運行,然後主進程退出。你可以簡單地通過運行任何分支到後臺的程序來嘗試它,例如gvim
,只要它被配置爲在執行後在後臺運行:set res [exec gvim]
。如果進程分叉並退出,Tcl [exec]進程會離開殭屍
理論上主進程立即退出,子進程在後臺運行,但不知何故主進程掛斷,不退出,停留在殭屍狀態(報告爲<defunct>
,在ps
輸出)。
在我的情況下,我開始打印的東西,我想要的東西,我希望該過程退出,我說完成。問題是,如果我使用open "|gvim" r
產生了這個過程,那麼我無法識別過程結束的時刻。由[open]
返回的fd
從不報告[eof]
,即使程序變成殭屍。當我嘗試[read]
時,只是爲了讀取該進程可能打印的所有內容,完全掛起。
更有趣的是,偶爾主進程和分叉進程都會打印某些內容,當我試圖使用[gets]
來讀取它時,我同時得到了這兩個文件。如果我太早關閉描述符,則[close]
由於管道損壞而引發異常。可能這就是爲什麼[read]
永遠不會結束。
我需要一些方法來識別當進程退出時的時刻,而這個進程可能產生了另一個子進程,但是這個子進程可能完全脫離了,我對它的作用並不感興趣。我想要在退出之前主進程打印的內容,並且腳本應該繼續其工作,而在後臺運行的進程也在運行,並且我不關心它發生了什麼。
我可以控制我開始的過程的來源。是的,我在fork()
之前做過signal(SIGCLD, SIG_IGN)
- 沒有幫助。
我不知何故知道你是唯一合理回答的人:)。不幸的是,你的解決方案沒有一個能夠工作:第一個解決方案掛在'gets'上,它是'exec'上的線程化解決方案。這可以通過'gvim'很容易地證明(我給它只是爲了可以很容易地測試它)。我需要一個解決方案:接受套接字連接,獲取命令,在bg中運行一個進程,忘記它。另一個請求可能會殺死它,但該進程將被cmdline args識別。我也不必自己製作流程叉,我只是覺得它會更容易。也可以執行'exec ...&''slongs我可以退出並保持它運行 – Ethouris
我認爲如果你對這個主題有點興趣,它會很好。 'bash'中不存在這個問題 - 你運行一個進程分叉到後臺並且它正在運行,CLI返回。在Tcl中做同樣的事情,'[exec]'命令不會返回(永遠掛起,退出的過程像殭屍一樣)。它是否真的按照設計工作?正常情況下,殭屍將退出由父母清理的CHILD進程。不過,不管怎樣,相同的CHILD進程不會分叉任何東西,沒有任何殭屍就退出。你能解釋一下嗎? – Ethouris