2017-04-12 83 views
0

我有一個處理請求的應用程序(使用2.7)。當收到「A」類型的請求時,我需要啓動一個外部進程。Python外部進程沒有終止

當收到類型「B」的請求時,我需要檢查並看看外部進程是否已完成,然後根據它是否已完成做一些事情。

我遇到的問題是,當外部過程完成時不退出,它會變成殭屍狀態,例如:

1 Z root  13703 13644 0 80 0 -  0 exit 09:37 ? 00:00:00 [python] <defunct> 

最初我開始用POPEN這樣的過程:

DEVNULL = open(os.devnull, "wb") 
subprocess.Popen(cmd+args, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True) 

我嘗試使用os.spawn:

os.spawnv(os.P_NOWAIT, 'python', cmd+args) 

但仍然過程中沒有 出口。

任何人都知道我可以如何獲得外部進程終止時完成?

+0

提供有關'外部process'一些信息。 – stovfl

+0

看起來問題在於你的外部進程,而不是啓動它的Python程序。完成後是否關閉? –

回答

4

一個進程成爲殭屍,直到其父進程收回它。你可以閱讀有關如何/爲什麼一個過程變爲https://unix.stackexchange.com/questions/105998/why-process-program-becomes-zombie

對於你的情況殭屍,你首先應該保持一個變量創建POPEN()對象的詳細信息,然後就可以在該對象上調用的poll()檢查當它完成執行時。一旦你調用poll()並且如果該子進程已經完成執行(即,達到了殭屍狀態),那麼poll()將自動清理該子進程。

p = subprocess.Popen(cmd+args, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True) 

在收到請求的B,你可以做

p.poll() 

這將返回過程的返回碼或None如果還沒有完成。

關於不同的功能,你可以POPEN對象調用的更多信息:https://docs.python.org/2/library/subprocess.html#popen-objects

+0

是的,這是問題所在。我無法保存Popen()對象,因爲我的持久性存儲是數據庫。但我確實保存了pid,所以我可以在'os.waitpid()'中使用它。非常感謝! –