Cla*_*ara 28 python linux subprocess
我在linux机器上运行一个python脚本,它使用subprocess.check_output()创建一个子进程,如下所示:
subprocess.check_output(["ls", "-l"], stderr=subprocess.STDOUT)
Run Code Online (Sandbox Code Playgroud)
问题是,即使父进程死亡,子进程仍在运行.当父母去世时,我有什么办法可以杀死孩子的过程吗?
mic*_*ses 24
是的,您可以通过两种方法实现这一目标.它们都要求你使用Popen而不是check_output.第一个是更简单的方法,使用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()
Run Code Online (Sandbox Code Playgroud)
这将捕获sigint(键盘中断)和sigterm,但不是sigkill(如果你用-9杀死你的脚本).
另一种方法有点复杂,并使用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))
Run Code Online (Sandbox Code Playgroud)
cda*_*rke 21
你的问题是使用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
Run Code Online (Sandbox Code Playgroud)
要确保在退出时杀死孩子:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44656 次 |
| 最近记录: |