在Python 3'中避免竞争条件;s多处理队列

在Python 3'中避免竞争条件;s多处理队列,python,python-3.x,parallel-processing,race-condition,Python,Python 3.x,Parallel Processing,Race Condition,我试图找到最大重量约61亿(定制)项目,我想这样做与并行处理。对于我的特定应用程序,有一些更好的算法不需要我迭代61亿项,但解释它们的教科书是我无法理解的,我的老板希望在4天内完成。我想我有一个更好的机会使用我公司的奇特服务器和并行处理。然而,我所知道的关于并行处理的一切都来自于阅读。也就是说我很迷路 我目前的理论是建立一个feeder进程、一个输入队列、一整组(比如说,30个)工作进程和一个输出队列(在输出队列中找到最大元素将非常简单)。我不明白的是,feeder进程如何告诉worker进程何

我试图找到最大重量约61亿(定制)项目,我想这样做与并行处理。对于我的特定应用程序,有一些更好的算法不需要我迭代61亿项,但解释它们的教科书是我无法理解的,我的老板希望在4天内完成。我想我有一个更好的机会使用我公司的奇特服务器和并行处理。然而,我所知道的关于并行处理的一切都来自于阅读。也就是说我很迷路

我目前的理论是建立一个feeder进程、一个输入队列、一整组(比如说,30个)工作进程和一个输出队列(在输出队列中找到最大元素将非常简单)。我不明白的是,feeder进程如何告诉worker进程何时停止等待项目通过输入队列

我曾经考虑过在我的6.1E9项目的iterable上使用
multiprocessing.Pool.map\u async
,但是只需迭代这些项目而不对它们做任何操作就需要将近10分钟除非我误解了什么…,让
map\u async
迭代它们以将它们分配给进程可以在进程开始工作时完成。(
Pool
也提供了
imap
,但是说它类似于
map
,它似乎不异步工作。我想要异步,对吗?

相关问题:我是否要使用
并发.futures
而不是
多处理
?我不可能是第一个实施两个排队系统的人(这正是美国每个熟食店排队的方式…),那么有没有更具Pythonic/内置的方法来实现这一点

这是我想做的事情的基本情况<强>在中间看到注释块。< /强>

将多处理导入为mp
导入队列
def水龙头(项目、浴缸):
“”“将6.1e9项填充浴缸(一个过程安全队列)”
对于项目中的项目:
浴缸。放置(物品)
浴缸关上
def排放过滤器(浴缸、排放口):
“”“将浴缸中的物品放入排水管中。”。
浴缸和排水管是过程安全队列。
"""
最大重量=0
最大项=无
尽管如此:
尝试:
当前_项=bathbub.get()
#下面的三行是我无法理解的
#我很清楚如何在没有竞争条件的情况下触发。
#我最想做的就是在水龙头响后触发它们
#浴缸。关闭,浴缸队列为空。
队列除外。空:
排水。放置((最大重量,最大项目))
返回
其他:
浴缸。任务完成()
如果不是,则项目“”是否相关()
持续
当前重量=项目重量
如果当前重量>最大重量:
最大重量=当前重量
最大项目=当前项目
def并行_最大值(项目,NPROC=30):
“”项的元素应该有一个与“”相关的方法`
属性'weight'。'items'本身是不可变的
迭代器对象。
"""
浴缸q=mp.JoinableQueue()
drain_q=mp.Queue()
水龙头流程=mp.流程(目标=水龙头,参数=(项目,浴缸)
工作进程=mp.Pool(进程=NPROC)
水龙头程序启动()
工人程序应用异步(排水过滤器、浴缸、排水管)
决赛选手=[]
对于范围内的i(NPROC):
追加(drain_q.get())
返回最大值(决赛选手)

答案是这样的 我对我的问题找到了一个非常彻底的答案,并对Python基金会通信总监Doug Hellman的多任务进行了温和的介绍。我想要的是“毒丸”图案。请在此处查看:


@MRAB的道具,用于发布该概念的核心。

您可以在队列中放入一个特殊的终止项,例如None。当一个工作人员看到它时,它可以将它放回给其他工作人员看,然后终止。或者,您可以将每个工作人员的一个特殊终止项放入队列。

这是一个非常好的答案。我会把这个问题留长一点,以防有人能回答相关的问题。所以我把
浴缸。在关闭队列之前,在
水龙头()的末尾放(无)
,但是我该如何处理
任务_done()
调用?或者我只是从使用
可连接队列
切换到常规的
队列
,并摆脱所有的
任务_done()
调用吗?如果您使用的是
多处理。队列
,为什么要导入队列?我使用它捕获
队列。当工作人员查看其输入队列时,会出现空的
异常。我一厢情愿的想法是,如果且仅当队列已关闭且也为空时,才会抛出该异常。请注意,在@MRAB的答案中的方法下,导入
queue
是不必要的。