在Python中对使用多进程创建的进程使用join()方法

3 投票
2 回答
3817 浏览
提问于 2025-04-19 12:50

我正在使用多进程模块中的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 个回答

0

join() 对子进程没有任何作用。如果你真的想以不太干净的方式结束工作进程,你应该使用 terminate()(不过你得明白这样做的后果)。如果你希望子进程在主进程退出时自动结束,你应该把它们的 daemon 属性设置为真。

3

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是不会有什么问题的。

撰写回答