2014-02-09 41 views
7

從Python終端,我運行一些命令像下面,產卵長時間運行的子進程:Python的多和孩子的獨立性處理

from multiprocessing.process import Process 
Process(target=LONG_RUNNING_FUNCTION).start() 

此命令返回,我可以做其他的事情蟒蛇終端,但任何由孩子打印的內容仍然會打印到我的Python終端會話中。

當我退出終端(具有exitCTRL + d),它掛起退出命令。如果我在此掛起期間點擊了CTRL + C,子進程終止。

如果我手動終止python終端進程(通過posix kill命令),子進程將被孤立,並繼續運行,其輸出可能被丟棄。

如果我python -c運行這段代碼,它等待子終止,並CTRL +ç殺死雙方父母和孩子。

哪些運行配置的python會在父母終止時殺死孩子?特別是,如果一個python-mod_wsgi-apache web服務器產生子進程然後重新啓動,那麼這些子進程是否被殺死?

[順便說一下,分離終端產生的子進程的正確方法是什麼?有沒有一種方法比下面更優雅:Deliberately make an orphan process in python]

更新:通過下運行的Apache Web服務器與multiprocessing.Process催生蟒子過程重新啓動Apache的時候殺害。

回答

12

這不是你如何調用python的問題;這是multiprocessing模塊的一項功能。當您導入該模塊時,將退出處理程序添加到父進程,該父進程在允許父進程退出之前通過multiprocessing.Process創建的所有子進程的Process對象上調用join()。如果你打算以這種方式啓動子進程,那麼就沒有辦法,不要黑客模塊內部的東西,以避免給你帶來麻煩的行爲。

如果你想開始一個能夠超越父母的過程,那麼你可能會更好地使用subprocess.Popen服務。如果孩子的就這樣開始了,父母不會嘗試退出前加入孩子而會立即退出,留下一個孤兒:

>>> from subprocess import Popen 
>>> Popen(["sleep", "100"]) 
<subprocess.Popen object at 0x10d3fedd0> 
>>> exit() 
alp:~ $ ps -opid,ppid,command | grep sleep | grep -v grep 
37979  1 sleep 100 

是否有您所使用multiprocessing代替subprocess一個特別的理由?前者不打算用於創建意味着比父母更有生氣的兒童過程;它是爲了創建子進程來完成可以在CPU之間進行有效並行處理的工作,作爲規避Global Interpreter Lock的一種方式。 (爲了討論的目的,我忽略了multiprocessing的分佈式功能。)multiprocessing因此通常用於那些如果沒有GIL的情況下,您將使用線程。 (請注意,在這方面,multiprocessing模塊的API模塊接近於threading模塊的模型。)

針對您帖子末尾的具體問題:(1)當父母被終止時,沒有任何關於python的內容負責殺害孩子。如果父服務器在退出之前將其殺死(或者如果整個進程組被終止),那麼只能殺死Web服務器的子進程。 (2)你鏈接的方法看起來好像它試圖複製守護進程而不知道這樣做的標準習慣用法。有很多軟件包用於創建守護進程;你應該使用其中的一個。

+0

子進程是我調度系統調用的前往模塊,但使用子進程啓動後臺python任務似乎不合適。你有沒有使用一個好的python-deamon庫(比如python-deamon)? – Zags

+1

背景/前景區分特定於外殼中的作業控制;通常在應用中使用這些術語來處理管理是沒有意義的。在更一般的上下文中,守護進程是一個進程爲自己執行的事情,使用'subprocess.Popen'來啓動這樣的進程是完全標準的。 'python-daemon'很好;它有一個麻煩的API,但它是經過測試的,而後者的質量很重要,因爲很容易弄錯這種事情。 – Alp