web-dev-qa-db-ja.com

実行中のサブプロセス呼び出しを強制終了します

Pythonでsubprocessを使用してプログラムを起動しています。

場合によっては、プログラムがフリーズすることがあります。これは私の制御不能です。起動されたコマンドラインからできることは CtrlEsc これにより、プログラムが迅速に終了します。

subprocessでこれをエミュレートする方法はありますか? subprocess.Popen(cmd, Shell=True)を使用してプログラムを起動しています。

12
Thomas O
p = subprocess.Popen("echo 'foo' && sleep 60 && echo 'bar'", Shell=True)
p.kill()

詳細については、subprocessモジュールのドキュメントを参照してください。 http://docs.python.org/2/library/subprocess.html

17
butch

さて、subprocess.Popen()によって返されるオブジェクトには、 Popen.terminate() および Popen.kill() 、それぞれSIGTERMおよびSIGKILLを送信します。

例えば...

_import subprocess
import time

process = subprocess.Popen(cmd, Shell=True)
time.sleep(5)
process.terminate()
_

... 5秒後にプロセスを終了します。

または、 os.kill() を使用して、CTRL-CをシミュレートするSIGINTなどの他の信号を送信できます。

_import subprocess
import time
import os
import signal

process = subprocess.Popen(cmd, Shell=True)
time.sleep(5)
os.kill(process.pid, signal.SIGINT)
_
22
Aya

あなたの質問はあまり明確ではありませんが、あなたがゾンビに行くプロセスを起動しようとしていると仮定すると、スクリプトのある状態でそれを制御できるようにしたいです。この場合、次のことを提案します。

p = subprocess.Popen([cmd_list], Shell=False)

これは実際にシェルを通過することをお勧めしません。 Shell = Falseを使用することをお勧めします。これにより、オーバーフローのリスクを減らすことができます。

# Get the process id & try to terminate it gracefuly
pid = p.pid
p.terminate()

# Check if the process has really terminated & force kill if not.
try:
    os.kill(pid, 0)
    p.kill()
    print "Forced kill"
except OSError, e:
    print "Terminated gracefully"
1
ScotchAndSoda

2つのシグナルを使用して、実行中のサブプロセスコール、つまりsignal.SIGTERMとsignal.SIGKILLを強制終了できます。例えば

import subprocess
import os
import signal
import time
..
process = subprocess.Popen(..)
..
# killing all processes in the group
os.killpg(process.pid, signal.SIGTERM)
time.sleep(2)
if process.poll() is None:  # Force kill if process is still alive
    time.sleep(3)
    os.killpg(process.pid, signal.SIGKILL)
0
Asif Hasnain