python中进程join函数_通过定期调用'join()避免僵死进程`

正如@Giannis在一篇评论中建议的那样,您正在从头开始重塑流程管理器。坚持Python的特性,您是否反对使用multiprocessing.Pool?如果是,怎么办?在

通常的方法是选择要同时运行的最大工作进程数。说NUM_WORKERS = 4

然后将它作为receive()函数的替代:

^{pr2}$

NUM_WORKERS进程只创建一次,并跨任务重用。如果出于某种原因,您需要(或希望)为每个任务创建一个全新的进程,则只需将maxtasksperchild=1添加到Pool构造函数中。在

如果出于某种原因,您需要知道每个任务何时完成,您可以,例如,在apply_async()调用中添加一个callback=参数,并编写一个小函数,该函数将在任务结束时被调用(它将作为参数接收worker()函数返回的内容)。在

恶魔就在恶魔之列

因此,您的实际应用程序中的工作进程希望(无论出于什么原因)创建自己的进程,Pool创建的进程不能这样做。它们被创建为“守护进程”。从文件中:When a process exits, it attempts to terminate all of its daemonic child processes.

Note that a daemonic process is not allowed to create child processes. Otherwise a daemonic process would leave its children orphaned if it gets terminated when its parent process exits.

非常清楚;-)这里有一种精心设计的方法来创建您自己的Pool工作方式,它创建了非守护进程,但对我的口味来说太过复杂了:

回到您原来的设计,您已经知道它是可行的,我只需更改它,将周期性地加入工作进程的逻辑与操作队列的逻辑分开。从逻辑上讲,他们真的没有任何关系。具体来说,创建一个“后台线程”来加入对我来说很有意义:def reap(workers, quit):

from time import sleep

while not quit.is_set():

to_join = [w for w in workers if not w.is_alive()]

for p_worker in to_join:

print(f"Join {p_worker.name}")

p_worker.join()

workers.remove(p_worker)

sleep(2) # whatever you like

for p_worker in workers:

print(f"Join {p_worker.name}")

p_worker.join()

def receive(q: mp.Queue):

import threading

workers = [] # type: List[mp.Process]

quit = threading.Event()

reaper = threading.Thread(target=reap, args=(workers, quit))

reaper.start()

while True:

request = q.get()

if request == "EOF":

break

p_worker = mp.Process(target=worker, args=(request,), name=request)

p_worker.start()

workers.append(p_worker)

quit.set()

reaper.join()

我碰巧知道,list.append()和{}在CPython中是线程安全的,因此不需要使用锁来保护这些操作。但如果你再加一个也没什么坏处。在

再来一个试试

虽然Pool创建的进程是守护进程,但类似的concurrent.futures.ProcessPoolExecutor创建的进程似乎不是。所以我的第一个建议的这个简单的变化可能对你有用(或者不一定;-):NUM_WORKERS = 4

def receive(q: mp.Queue):

import concurrent.futures as cf

with cf.ProcessPoolExecutor(NUM_WORKERS) as e:

while True:

request = q.get()

if request == "EOF":

break

e.submit(worker, request)

如果这对你有用,很难想象有什么实质上更简单的事情。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值