这是this的后续问题。用户将建议使用队列,我试图在下面实现该解决方案。该解决方案在j = 1000时运行良好,但是,当我尝试扩展到更大的数字时,它会挂起。我被困在这里,无法确定它挂起的原因。任何建议,将不胜感激。此外,代码开始变得丑陋,因为我一直在搞乱它,我为所有嵌套函数道歉。
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()
答案 0 :(得分:1)
你将'STOP'
毒药放入你的uncrunched_queue
(你应该),并让你的生产者相应关闭;另一方面,您的消费者只检查被挤压队列的空虚:
while not crunched_queue.empty():
(这个
当你开始向你的bazinga
生产者投掷非平凡的工作单位时,他们需要更长的时间。如果所有这些都花了足够长的时间,你的crunched_queue
会干涸,而你的消费者就会死亡。我想你可能会错误地识别正在发生的事情 - 你的程序没有“挂起”,它只是停止输出东西,因为你的消费者已经死了。
您需要实施更智能的方法来关闭您的消费者。要么查找 n 毒丸,其中 n 是生产者的数量(因此每个人在关闭时每个人在crunched_queue
中抛出一个),或者使用某些东西就像一个Semaphore
计算每个现场制作人一样,当一个人关闭时就算下来。