Popen で開始し、サブプロセスを開始するいくつかのプロセスに苦労しています。端末でこれらのプロセスを手動で開始すると、CTRL + C を送信すると、すべてのプロセスが期待どおりに終了します。しかし、subprocess.Popen を使用して Python プログラム内で実行すると、プロセスを終了しようとすると、親は削除されますが、子は削除されません。
.terminate() ..kill() と ..send_signal() を signal.SIGBREAK、signal.SIGTERM で試しましたが、いずれの場合も親プロセスを終了するだけです。
この親プロセスを使用すると、不正な動作を再現できます。
#!/usr/bin/python
import time
import sys
import os
import subprocess
import signal
if __name__ == "__main__":
print os.getpid(), "MAIN: start a process.."
p = subprocess.Popen([sys.executable, 'process_to_shutdown.py'])
print os.getpid(), "MAIN: started process", p.pid
time.sleep(2)
print os.getpid(), "MAIN: kill the process"
# these just terminate the parent:
#p.terminate()
#p.kill()
#os.kill(p.pid, signal.SIGINT)
#os.kill(p.pid, signal.SIGTERM)
os.kill(p.pid, signal.SIGABRT)
p.wait()
print os.getpid(), "MAIN: job done - ciao"
実際の子プロセスは、いくつかのサブプロセスを生成して CRTL-C を待機する Django の manage.py です。ただし、次の例も機能するようです。
#!/usr/bin/python
import time
import sys
import os
import subprocess
if __name__ == "__main__":
timeout = int(sys.argv[1]) if len(sys.argv) >= 2 else 0
if timeout == 0:
p = subprocess.Popen([sys.executable, '-u', __file__, '13'])
print os.getpid(), "just waiting..."
p.wait()
else:
for i in range(timeout):
time.sleep(1)
print os.getpid(), i, "alive!"
sys.stdout.flush()
print os.getpid(), "ciao"
つまり、私の質問は簡単に言えば、最初の例でプロセスを強制終了し、子プロセスも削除するにはどうすればよいですか? Windows では os.kill(p.pid, signal.CTRL_C_EVENT) が機能する場合があるようですが、正しい方法は何ですか? そして、ターミナルはどのようにそれを行うのですか?