GNU/Linux >> Linux の 問題 >  >> Linux

親プロセスが終了したときに、subprocess.check_output() で作成された python 子プロセスを強制終了する方法は?

はい、2 つの方法でこれを実現できます。どちらも Popen を使用する必要があります check_output の代わりに . 1 つ目は、次のように try..finally を使用する簡単な方法です:

from contextlib import contextmanager

@contextmanager
def run_and_terminate_process(*args, **kwargs):
try:
    p = subprocess.Popen(*args, **kwargs)
    yield p        
finally:
    p.terminate() # send sigterm, or ...
    p.kill()      # send sigkill

def main():
    with run_and_terminate_process(args) as running_proc:
        # Your code here, such as running_proc.stdout.readline()

これは sigint (キーボード割り込み) と sigterm をキャッチしますが、sigkill (スクリプトを -9 で強制終了した場合) はキャッチしません。

もう 1 つの方法はもう少し複雑で、ctypes の prctl PR_SET_PDEATHSIG を使用します。親がなんらかの理由 (sigkill でさえも) で終了すると、システムは子にシグナルを送信します。

import signal
import ctypes
libc = ctypes.CDLL("libc.so.6")
def set_pdeathsig(sig = signal.SIGTERM):
    def callable():
        return libc.prctl(1, sig)
    return callable
p = subprocess.Popen(args, preexec_fn = set_pdeathsig(signal.SIGTERM))

あなたの問題は subprocess.check_output の使用にあります - そのインターフェースを使用して子 PID を取得することはできません。代わりに Popen を使用してください:

proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE)

# Here you can get the PID
global child_pid
child_pid = proc.pid

# Now we can wait for the child to complete
(output, error) = proc.communicate()

if error:
    print "error:", error

print "output:", output

終了時に子供を確実に殺すには:

import os
import signal
def kill_child():
    if child_pid is None:
        pass
    else:
        os.kill(child_pid, signal.SIGTERM)

import atexit
atexit.register(kill_child)

Linux
  1. 親が終了した後に子プロセスを終了させる方法は?

  2. Python で親プロセスの環境を変更することは可能ですか?

  3. 親プロセスの作業ディレクトリを設定するにはどうすればよいですか?

  1. 親プロセスが終了したときの新しい親プロセス?

  2. nohupプロセスを強制終了するプロセスIDを取得するには?

  3. プロセス名でPIDを取得するには?

  1. 親が初期化されているプロセスを強制終了する方法は?

  2. Kali は今後の Python 2 のサポート終了にどのように対処するか

  3. shell=True で起動された Python サブプロセスを終了する方法