干净的Python多进程终止依赖于退出标志
我正在尝试使用多个进程创建一个程序,如果出现错误,我希望干净地终止所有生成的进程。下面我已经为我认为需要做的事情编写了一些伪类型代码,但我不知道最好的方法是如何与所有进程通信,告诉它们发生了错误,它们应该终止 我想我应该使用类来完成这类事情,但我对Python还很陌生,所以我只是想先了解一下基本知识干净的Python多进程终止依赖于退出标志,python,process,parallel-processing,multiprocessing,Python,Process,Parallel Processing,Multiprocessing,我正在尝试使用多个进程创建一个程序,如果出现错误,我希望干净地终止所有生成的进程。下面我已经为我认为需要做的事情编写了一些伪类型代码,但我不知道最好的方法是如何与所有进程通信,告诉它们发生了错误,它们应该终止 我想我应该使用类来完成这类事情,但我对Python还很陌生,所以我只是想先了解一下基本知识 #imports exitFlag = True # Function for threads to process def url_thread_worker( ): # whil
#imports
exitFlag = True
# Function for threads to process
def url_thread_worker( ):
# while exitFlag:
try:
# do something
except:
# we've ran into a problem, we need to kill all the spawned processes and cleanly exit the program
exitFlag = False
def processStarter( ):
process_1 = multiprocessing.Process( name="Process-1", target=url_thread_worker, args=( ) )
process_2 = multiprocessing.Process( name="Process-2", target=url_thread_worker, args=( ) )
process_1.start()
process_2.start()
if __name__ == '__main__':
processStarter( )
提前感谢以下是我的建议:
import multiprocessing
import threading
import time
def good_worker():
print "[GoodWorker] Starting"
time.sleep(4)
print "[GoodWorker] all good"
def bad_worker():
print "[BadWorker] Starting"
time.sleep(2)
raise Exception("ups!")
class MyProcManager(object):
def __init__(self):
self.procs = []
self.errors_flag = False
self._threads = []
self._lock = threading.Lock()
def terminate_all(self):
with self._lock:
for p in self.procs:
if p.is_alive():
print "Terminating %s" % p
p.terminate()
def launch_proc(self, func, args=(), kwargs= {}):
t = threading.Thread(target=self._proc_thread_runner,
args=(func, args, kwargs))
self._threads.append(t)
t.start()
def _proc_thread_runner(self, func, args, kwargs):
p = multiprocessing.Process(target=func, args=args, kwargs=kwargs)
self.procs.append(p)
p.start()
while p.exitcode is None:
p.join()
if p.exitcode > 0:
self.errors_flag = True
self.terminate_all()
def wait(self):
for t in self._threads:
t.join()
if __name__ == '__main__':
proc_manager = MyProcManager()
proc_manager.launch_proc(good_worker)
proc_manager.launch_proc(good_worker)
proc_manager.launch_proc(bad_worker)
proc_manager.wait()
if proc_manager.errors_flag:
print "Errors flag is set: some process crashed"
else:
print "Everything closed cleanly"
您需要为每个进程运行一个等待其结束的包装线程。
当进程结束时,检查exitcode:if>0,表示它引发了一些未处理的异常。现在调用terminate_all()关闭所有剩余的活动进程。
包装线程也将完成,因为它们依赖于进程运行
此外,在代码中,您完全可以随时调用proc_manager.terminate_all()。您可以在不同的线程或类似的东西中检查一些标志
希望这对你的案子有好处
附言:顺便说一句。。在您的原始代码中,您做了一些类似于全局退出标志的事情:在多处理中,您永远不能有“全局”退出标志,因为它根本不是全局的,因为您使用的是带有分离内存空间的分离进程。这只适用于状态可以共享的线程化环境。如果在多处理中需要它,那么如果希望在父进程退出时自动终止子进程,则必须在进程之间进行显式通信()或类似的通信;您可以将它们设为daemonic(在
.start()
之前设置.daemon=True
),也就是说,如果父级检测到错误;它可能会退出——孩子们会得到照顾的
如果你想让孩子们自己打扫卫生;你可以:
这是一个很好的例子,帮助很大。非常感谢。你选择了处理“容易的部分”——当孩子们死去时。但如果父母死了呢?然后您将剩下孤立的进程(工作进程)。至少对我来说,这是一个大问题。这是一个需要解决的大不相同的案例,并不常见。您应该对系统进行编码,以确保父进程能够适应错误,并且如果出现问题,它至少可以终止子进程。
import multiprocessing
def event_func(event):
print '\t%r is waiting' % multiprocessing.current_process()
event.wait()
print '\t%r has woken up' % multiprocessing.current_process()
if __name__ == '__main__':
event = multiprocessing.Event()
processes = [multiprocessing.Process(target=event_func, args=(event,))
for i in range(5)]
for p in processes:
p.start()
print 'main is sleeping'
time.sleep(2)
print 'main is setting event'
event.set()
for p in processes:
p.join()