在Python中优化多处理(后续:使用队列)
这是我们的后续问题。用户将建议使用队列,我尝试实现下面的解决方案。该解决方案在j=1000时运行良好,但是,当我尝试扩展到更大的数字时,它挂起。我被困在这里,无法确定它为什么会挂起来。如有任何建议,将不胜感激。此外,代码开始变得丑陋,因为我一直在搞乱它,我为所有嵌套函数道歉在Python中优化多处理(后续:使用队列),python,multiprocessing,Python,Multiprocessing,这是我们的后续问题。用户将建议使用队列,我尝试实现下面的解决方案。该解决方案在j=1000时运行良好,但是,当我尝试扩展到更大的数字时,它挂起。我被困在这里,无法确定它为什么会挂起来。如有任何建议,将不胜感激。此外,代码开始变得丑陋,因为我一直在搞乱它,我为所有嵌套函数道歉 def run4(j): """ a multicore approach using queues """ from multiprocessing import Process, Queu
def run4(j):
"""
a multicore approach using queues
"""
from multiprocessing import Process, Queue, cpu_count
import os
def bazinga(uncrunched_queue, crunched_queue):
"""
Pulls the next item off queue, generates its collatz
length and
"""
num = uncrunched_queue.get()
while num != 'STOP': #Signal that there are no more numbers
length = len(generateChain(num, []) )
crunched_queue.put([num , length])
num = uncrunched_queue.get()
def consumer(crunched_queue):
"""
A process to pull data off the queue and evaluate it
"""
maxChain = 0
biggest = 0
while not crunched_queue.empty():
a, b = crunched_queue.get()
if b > maxChain:
biggest = a
maxChain = b
print('%d has a chain of length %d' % (biggest, maxChain))
uncrunched_queue = Queue()
crunched_queue = Queue()
numProcs = cpu_count()
for i in range(1, j): #Load up the queue with our numbers
uncrunched_queue.put(i)
for i in range(numProcs): #put sufficient stops at the end of the queue
uncrunched_queue.put('STOP')
ps = []
for i in range(numProcs):
p = Process(target=bazinga, args=(uncrunched_queue, crunched_queue))
p.start()
ps.append(p)
p = Process(target=consumer, args=(crunched_queue, ))
p.start()
ps.append(p)
for p in ps: p.join()
您正在将
'STOP'
毒药放入您的未运行的队列中
(您应该这样做),并相应地关闭您的生产商;另一方面,您的消费者只检查拥挤队列的空性:
while not crunched_queue.empty():
(这完全取决于比赛条件,顺便说一句,这并不好)
当你开始向你的bazinga
制作人抛出非琐碎的工作单元时,它们需要更长的时间。如果所有这些花费足够长的时间,你的拥挤的队列就会干涸,你的消费者就会死亡。我认为你可能误判了正在发生的事情——你的程序没有“挂起”,它只是停止输出东西,因为你的消费者已经死了
您需要实施更智能的方法来关闭您的消费者。或者寻找n个毒药丸,其中n是生产商的数量(当他们关闭时,每个生产商相应地将一个毒药丸扔进crunched_队列中),或者使用类似于的信号灯,对每个活着的生产商计数,当一个生产商关闭时计数。我在bazinga()的末尾添加了以下内容:crunched_队列。put(['STOP','STOP'])
并且我向消费者添加了一个计数器,以便在收到适当数量的停止后停止。这很好,但是,脚本似乎没有使用多个处理器(在我的活动管理器中只有一个Python进程,而不是numProcs+1)当j>10000时,这会导致运行速度非常慢。我在最初的帖子中将问题分解为处理器之间的块。很好,你知道为什么这篇文章不会这样做吗?