3

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) が機能する場合があるようですが、正しい方法は何ですか? そして、ターミナルはどのようにそれを行うのですか?

4

1 に答える 1

0

Henri Korhonen がコメントで述べたように、グループ化プロセスが役立つはずです。さらに、Windows を使用していて、これが Windows アプリケーションを起動する Cygwin Python である場合、Cygwin Python は子を強制終了できないようです。そのような場合、TASKKILL を実行する必要があります。TASKKILL は、グループ パラメータも受け取ります。

于 2014-03-14T16:30:56.887 に答える