Pythonのsubprocessでkillが効かないときの対処法
はじめに
Pythonのsubprocess.Popen
を使って,サブプロセスを起動・終了させようとしたが終了だけうまくいかなかった.
原因と対処法をメモしておく.
結論
この現象は,subprocess.Popen
でshell=True
を指定していた場合に発生する.
対処法は,exec
コマンドを先頭にくっつけること.
subprocess.Popen('exec 実行するコマンド', shell=True)
再現手順
以下のように,起動する側(run.py)
と起動される側(wait.py)
の2つのスクリプトを書くと簡単に再現できた.
from subprocess import Popen
import time
p = Popen('python3 wait.py', shell=True)
time.sleep(5)
p.kill()
import time
for i in range(1000):
print(i)
time.sleep(1)
python run.py
を実行すると,run.py
の終了後もwait.py
のプロセスが存在したままになった.
一方で,Popenによって生成されたシェルのプロセスは正常に終了していた.
原因
subprocess.Popen
でshell=True
を指定していたため,コマンドはPopenによって起動されたシェルの中で実行されていた.
kill
コマンドによってシェルは正常に終了されるが,シェルによって起動されたコマンド(プロセス)は終了できていなかった.
対処法
上が原因であるとすれば,生成されたシェルと実行するコマンドが同じプロセスになればよい.
exec
コマンドを使うことで,生成されたシェルのプロセスの中でコマンドを実行させるようにする.
これで,.kill()
を実行すれば生成されたシェルとともに実行したコマンドも停止できるようになる(なった).
対策後のコードはこんな感じ.
from subprocess import Popen
import time
p = Popen('exec python3 wait.py', shell=True)
time.sleep(5)
p.kill()
さいごに
ここで紹介した方法以外にもプロセスグループを作るといった方法もあるらしい.(まだよくわかってない)
生成するプロセスの親子関係や,数が多い場合は考えるべきかもしれない.
Author And Source
この問題について(Pythonのsubprocessでkillが効かないときの対処法), 我々は、より多くの情報をここで見つけました https://qiita.com/lobmto/items/49f2a3fbfd913fcd35d5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .