mat*_*ick 5 python subprocess parent-child multiprocessing
我想要
已经有很多关于这些事情的文章,但我觉得我还没有找到我正在寻找的优雅的pythonic解决方案.我也试图让对于完全不熟悉python的人保持相对可读(和简短).
到目前为止我的方法(见下面的代码)是:
我试图避免定期轮询进程的解决方案,但我不确定原因.
有更好的方法吗?
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)
Run Code Online (Sandbox Code Playgroud)
一旦subprocess.call返回,子流程就完成了——并且call的返回值是子流程的returncode。因此,在列表中累积这些返回代码pids(顺便说一句,附加它的多进程和“主”进程之间不同步)并向它们发送9信号“就好像”它们是进程 ID 而不是返回代码,这绝对是错误的。
这个问题的另一件事肯定是错误的,那就是规范:
能够用“kill -9parent_process_pid”杀死它们。
因为这-9意味着父进程不可能拦截信号(这是显式指定的目的-9)——我想-9这里是虚假的。
您应该使用(每个“保姆”线程或进程,threading除了multiprocessing等待其子进程之外什么都不做,那么为什么要在这样一个轻量级任务上浪费进程呢?-); 您还应该调用suprocess.Process主线程(以启动子进程并能够获取其.pid放入列表中)并将生成的进程对象传递给等待它的保姆线程(当它完成时报告并删除从列表中选择)。子进程 ID 列表应该由锁保护,因为主线程和几个保姆线程都可以访问它,并且集合可能是比列表更好的选择(更快的删除),因为您不关心排序也不关心关于避免重复。
所以,粗略地(没有测试,所以可能存在错误;-)我会将您的代码更改为:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3621 次 |
| 最近记录: |