在Python中对使用多进程创建的进程使用join()方法
我正在使用多进程模块中的Process类来创建多个进程,这些进程会执行一些脚本,然后结束。我想要的是给每个进程设置一个超时时间,这样如果进程在规定时间timeout内没有执行完,就会被终止。我在Process对象上使用了join(timeout)
。
join()函数并不会杀死进程,它只是让主进程等待,直到子进程完成
。
现在我的问题是:使用join()
和timeout
会有什么副作用吗?比如,主进程结束后,这些子进程会自动被清理掉吗?还是说我需要手动去杀死这些进程?
我对Python和它的多进程模块还是个新手,请多多包涵。
我的代码是在一个循环中创建进程的:
q = Queue()
jobs = [
Process(
target=get_current_value,
args=(q,),
kwargs=
{
'device': device,
'service_list': service_list,
'data_source_list': data_source_list
}
) for device in device_list
]
for j in jobs:
j.start()
for k in jobs:
k.join()
2 个回答
join()
对子进程没有任何作用。如果你真的想以不太干净的方式结束工作进程,你应该使用 terminate()
(不过你得明白这样做的后果)。如果你希望子进程在主进程退出时自动结束,你应该把它们的 daemon
属性设置为真。
timeout
这个参数的意思是告诉join
要等多久,才能让Process
(进程)退出,如果超过这个时间就放弃等待。如果时间到了,Process
还没退出,join
就会直接返回,不再等待。如果你想在超时后结束你的工作进程,就需要手动去做。你可以使用terminate
,就像wRAR建议的那样,这样会比较粗暴地结束进程,或者使用其他的信号机制,告诉子进程要干净地退出:
p = Process(target=worker, args=(queue,))
p.start()
p.join(50)
if p.isalive(): # join timed out without the process actually finishing
#p.terminate() # unclean shutdown
如果你不想用terminate
,那另一种方法就要看你的工作进程在做什么了。如果它们是从队列中取数据,你可以使用一个哨兵(sentinel):
def worker(queue):
for item in iter(queue.get, None): # None will break the loop
# Do normal work
if __name__ == "__main__":
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=worker, args=(queue,))
p.start()
# Do normal work here
# Time to shut down
queue.put(None)
或者如果你在循环中做其他操作,可以使用Event
:
def worker(event):
while not event.is_set():
# Do work here
if __name__ == "__main__":
event= multiprocessing.Event()
p = multiprocessing.Process(target=worker, args=(event,))
p.start()
# Do normal work here
# Time to shut down
event.set()
其实使用terminate
也没问题,除非你的子进程正在使用一些资源,这些资源如果在进程意外关闭时可能会被损坏(比如写文件、数据库,或者持有锁)。如果你只是让工作进程做一些计算,使用terminate
是不会有什么问题的。