簡體   English   中英

如何在python中徹底殺死子進程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM