gpt4 book ai didi

python:杀死 child 或报告他们成功的简单方法?

转载 作者:太空狗 更新时间:2023-10-30 01:03:55 24 4
gpt4 key购买 nike

我要

  1. 并行调用 shell 命令(例如下面的“sleep”),
  2. 报告他们个人的开始和完成,以及
  3. 能够使用“kill -9 parent_process_pid”杀死它们。

已经有很多关于这类事情的文章,但我觉得我还没有完全找到我正在寻找的优雅的 pythonic 解决方案。对于完全不熟悉 python 的人,我还试图使内容相对可读(和简短)。

到目前为止,我的方法(见下面的代码)是:

  1. 将 subprocess.call(unix_command) 放在报告命令开始和完成的包装函数中。
  2. 使用 multiprocess.Process 调用包装函数。
  3. 跟踪适当的 pid,将它们全局存储,并在 signal_handler 中终止它们。

我试图避免使用定期轮询进程的解决方案,但我不确定为什么。

有没有更好的方法?

import subprocess,multiprocessing,signal
import sys,os,time

def sigterm_handler(signal, frame):
print 'You killed me!'
for p in pids:
os.kill(p,9)
sys.exit(0)

def sigint_handler(signal, frame):
print 'You pressed Ctrl+C!'
sys.exit(0)

signal.signal(signal.SIGINT, sigint_handler)
signal.signal(signal.SIGTERM, sigterm_handler)

def f_wrapper(d):
print str(d) + " start"
p=subprocess.call(["sleep","100"])
pids.append(p.pid)
print str(d) + " done"

print "Starting to run things."

pids=[]

for i in range(5):
p=multiprocessing.Process(target=f_wrapper,args=(i,))
p.daemon=True
p.start()

print "Got things running ..."

while pids:
print "Still working ..."
time.sleep(1)

最佳答案

一次subprocess.call返回,子流程完成——call 的返回值是子流程的returncode。因此,在列表 pids 中累积这些返回代码(顺便说一句,在附加它的多进程和“主”进程之间不同步)并向它们发送 9 信号“就好像”它们是进程 ID 而不是返回代码,这绝对是错误的。

另一个绝对错误的问题是规范:

be able to kill them with 'kill -9 parent_process_pid'.

因为 -9 意味着父进程不可能拦截信号(这就是显式指定 -9目的)- - 我想 -9 在这里是虚假的。

您应该使用 threading 而不是 multiprocessing(每个“保姆”线程或进程除了等待其子进程外什么都不做,所以为什么要浪费进程在这样一个轻量级的任务上?-);您还应该在主线程中调用 suprocess.Process(以启动子进程并能够获取其 .pid 以放入列表中)并传递生成的进程对象发送给等待它的保姆线程(当它完成时报告并将其从列表中删除)。子进程 ID 列表应该由锁保护,因为主线程和几个保姆线程都可以访问它,并且集合可能是比列表更好的选择(更快的删除),因为你不关心排序也不关心关于避免重复。

所以,大致(没有测试,所以可能存在错误;-)我会将您的代码更改为 s/thing like:

import subprocess, threading, signal
import sys, time

pobs = set()
pobslock = threading.Lock()
def numpobs():
with pobslock:
return len(pobs)

def sigterm_handler(signal, frame):
print 'You killed me!'
with pobslock:
for p in pobs: p.kill()
sys.exit(0)

def sigint_handler(signal, frame):
print 'You pressed Ctrl+C!'
sys.exit(0)

signal.signal(signal.SIGINT, sigint_handler)
signal.signal(signal.SIGTERM, sigterm_handler)

def f_wrapper(d, p):
print d, 'start', p.pid
rc = p.wait()
with pobslock:
pobs.remove(p)
print d, 'done, rc =', rc

print "Starting to run things."

for i in range(5):
p = subprocess.Popen(['sleep', '100'])
with pobslock:
pobs.add(p)
t = threading.Thread(target=f_wrapper, args=(i, p))
t.daemon=True
t.start()

print "Got things running ..."

while numpobs():
print "Still working ..."
time.sleep(1)

关于python:杀死 child 或报告他们成功的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3399246/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com