はい、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 カーネルモジュールで 1GB の HugePages に裏打ちされた DMA バッファを割り当てるにはどうすればよいですか?
独自のソフトウェアを Buildroot Linux パッケージに追加するにはどうすればよいですか?