我有兴趣使用the_pool
使用multiprocessing.Pool
进行通信来实例化一组工作人员Queue
。但是,每个worker都有一个参数role
,该参数对于该worker是唯一的,需要在worker初始化期间提供。这种约束是由我与之接口的API强加的,因此无法解决。如果我不需要队列,我可以迭代一个role
值列表并调用apply_async
,如下所示:
[the_pool.apply_async(worker_main, role) for role in roles]
不幸的是,Queue
对象只能在池实例化期间传递给池,如:
the_pool = multiprocessing.Pool(3, worker_main, (the_queue,))
尝试通过Queue
的参数传递apply_async
会导致运行时错误。在以下示例中,从this question改编,我们尝试实例化三个工作池。但是示例失败了,因为无法从roles
获取角色元素到池中的initargs
。
import os
import time
import multiprocessing
# A dummy function representing some fixed functionality.
def do_something(x):
print('I got a thing:', x)
# A main function, run by our workers. (Remove role arg for working example)
def worker_main(queue, role):
print('The worker at', os.getpid(), 'has role', role, ' and is initialized.')
# Use role in some way. (Comment out for working example)
do_something(role)
while True:
# Block until something is in the queue.
item = queue.get(True)
print(item)
time.sleep(0.5)
if __name__ == '__main__':
# Define some roles for our workers.
roles = [1, 2, 3]
# Instantiate a Queue for communication.
the_queue = multiprocessing.Queue()
# Build a Pool of workers, each running worker_main.
# PROBLEM: Next line breaks - how do I pass one element of roles to each worker?
the_pool = multiprocessing.Pool(3, worker_main, (the_queue,))
# Iterate, sending data via the Queue.
[the_queue.put('Insert useful message here') for _ in range(5)]
worker_pool.close()
worker_pool.join()
time.sleep(10)
一个简单的解决方法是在Queue
中包含第二个initargs
,它仅用于传达每个工作者的角色,并阻止工作程序执行,直到它通过该队列接收角色。但是,这会引入一个不必要的额外队列。相关文档为here。非常感谢指导和建议。
答案 0 :(得分:4)
为什么不使用两个工作器函数,一个仅用于初始化?像:
def worker_init(q):
global queue
queue = q
def worker_main(role):
# use the global `queue` freely here
初始化与您展示的内容大致相同,除了调用worker_init
:
the_pool = multiprocessing.Pool(3, worker_init, (the_queue,))
每个工作进程只执行一次初始化,每个进程一直持续到Pool
终止。要完成工作,请完成您想要做的事情:
[the_pool.apply_async(worker_main, role) for role in roles]
也没有必要传递the_queue
- 每个工作进程在初始化期间都已经了解过它。
答案 1 :(得分:0)
您可以使用角色创建队列:
then