我正在尝试通过队列学习多处理。
我想做的是找出脚本运行时何时/如何“将更多项目添加到队列”。
以下脚本是我正在使用的基准:
import multiprocessing
class MyFancyClass:
def __init__(self, name):
self.name = name
def do_something(self):
proc_name = multiprocessing.current_process().name
print('Doing something fancy in {} for {}!'.format(
proc_name, self.name))
def worker(q):
obj = q.get()
obj.do_something()
if __name__ == '__main__':
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=worker, args=(queue,))
p.start()
queue.put(MyFancyClass('Fancy Dan'))
queue.put(MyFancyClass('Frankie'))
print(queue.qsize())
# Wait for the worker to finish
queue.close()
queue.join_thread()
p.join()
在第26行,Fancy Dan
注入有效,但Frankie
无效。我能够确认Frankie
确实进入了队列。我需要一个可以“检查更多项目”并将其根据需要插入队列的位置。如果不存在更多项目,请在清除现有项目后关闭队列。
我该怎么做?
谢谢!
答案 0 :(得分:2)
让我们说清楚:
worker(q)
在上述方案中仅被调用一次。在第一次调用时,该函数将暂停等待阻塞操作q.get()
的结果。它从MyFancyClass('Fancy Dan')
获取实例queue
,调用其do_something
方法并完成操作。MyFancyClass('Frankie')
将被放入队列,但由于完成了流程的目标功能,因此不会进入流程。None
的值。import multiprocessing
class MyFancyClass:
def __init__(self, name):
self.name = name
def do_something(self):
proc_name = multiprocessing.current_process().name
print('Doing something fancy in {} for {}!'.format(proc_name, self.name))
def worker(q):
while True:
obj = q.get()
if obj is None:
break
obj.do_something()
if __name__ == '__main__':
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=worker, args=(queue,))
p.start()
queue.put(MyFancyClass('Fancy Dan'))
queue.put(MyFancyClass('Frankie'))
# print(queue.qsize())
queue.put(None)
# Wait for the worker to finish
queue.close()
queue.join_thread()
p.join()
输出:
Doing something fancy in Process-1 for Fancy Dan!
Doing something fancy in Process-1 for Frankie!
答案 1 :(得分:0)
您可以通过将worker更改为
def worker(q):
while not q.empty():
obj = q.get()
obj.do_something()
您的原始代码存在的问题是,工作人员在对队列中的一项进行处理后返回。您需要某种循环逻辑。
此解决方案是不完善的,因为empty()不是reliable。如果在添加更多项目之前队列变空,也会失败(该过程将返回)。
我建议使用Process Pool Executor。
Submit非常接近您要寻找的内容。