[英]How to cleanly kill subprocesses in python
我們使用python進程來管理長時間運行的python子進程。 偶爾需要殺死子程序。 kill命令不會完全終止進程,只會使其失效。
運行以下腳本演示了此行為。
import subprocess
p = subprocess.Popen(['sleep', '400'], stdout=subprocess.PIPE, shell=False)
要么
p = subprocess.Popen('sleep 400', stdout=subprocess.PIPE, shell=True)
將創建一個子進程。
p.terminate()
p.kill()
對這個過程沒有任何作用。 由ps aux | grep sleep
演示 ps aux | grep sleep
$ ps aux| grep 'sleep'
User 8062 0.0 0.0 7292 764 pts/7 S 14:53 0:00 sleep 400
這個過程沒有被殺死/被解散。 使用帶有'kill'
和pid
作為參數的subprocess.call()
函數將發出kill命令。
subprocess.call(['kill', str(p.pid)])
這會殺死這個過程,但它現在已經不存在了。
$ ps aux | grep 'sleep'
User 8062 0.0 0.0 0 0 pts/7 Z+ 14:51 0:00 [sleep] <defunct>
如果隊列運行的時間足夠長,它最終會達到最大進程數,還是最終會收到已解散的進程並且沒問題呢?
如果答案是前者,我如何在不殺死父進程的情況下處理python中的defunct進程?
有沒有更好的殺死進程的方法?
這里有兩個主要問題:
第一個問題:如果你使用的是shell=True
,那么你就是要殺死運行進程的shell ,而不是進程本身。 在其父母被殺害的情況下,子進程將無法立即/不會被殺死。
在你的情況下,你正在使用不是內置的sleep
,所以你可以刪除shell=True
,並且Popen
會產生實際的進程id: p.terminate()
可以工作。
您可以(並且您應該)在大多數情況下避免使用shell=True
,即使它需要額外的python編碼工作(將2個命令組合在一起,重定向輸入/輸出,所有這些情況都可以通過一個或多個Popen
很好地處理, 而不需要 shell=True
。
並且(第二期)如果在該修復之后終止該進程仍然不存在,則可以調用p.wait()
(來自此問題)。 似乎調用terminate
是不夠的。 Popen
對象需要進行垃圾回收。
你應該在終止子進程后調用p.wait()
來清除進程表。 這應該刪除僵屍進程(處於defunct
狀態)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.