python多核队列无原因地随机挂起,尽管队列大小很小
在python中,这里是我的多处理设置。我对Process方法进行了子类化,并给出了它 用于酸洗/数据目的的队列和一些其他字段 此策略在95%的时间内有效,其他5%的时间由于未知原因队列只是挂起并且永远不会结束(通常4个内核中有3个完成其任务,最后一个需要花费很长时间,因此我必须终止该任务) 我知道在python中队列的大小是固定的,否则它们将挂起。我的队列只存储一个字符串。。。处理器的id,所以不能是那样 下面是我的代码暂停的确切行:python多核队列无原因地随机挂起,尽管队列大小很小,python,python-2.7,multiprocessing,Python,Python 2.7,Multiprocessing,在python中,这里是我的多处理设置。我对Process方法进行了子类化,并给出了它 用于酸洗/数据目的的队列和一些其他字段 此策略在95%的时间内有效,其他5%的时间由于未知原因队列只是挂起并且永远不会结束(通常4个内核中有3个完成其任务,最后一个需要花费很长时间,因此我必须终止该任务) 我知道在python中队列的大小是固定的,否则它们将挂起。我的队列只存储一个字符串。。。处理器的id,所以不能是那样 下面是我的代码暂停的确切行: res = self._recv() 有人有想法吗?正
res = self._recv()
有人有想法吗?正式代码如下。
多谢各位
from multiprocessing import Process, Queue
from multiprocessing import cpu_count as num_cores
import codecs, cPickle
class Processor(Process):
def __init__(self, queue, elements, process_num):
super(Processor, self).__init__()
self.queue = queue
self.elements = elements
self.id = process_num
def job(self):
ddd = []
for l in self.elements:
obj = ... heavy computation ...
dd = {}
dd['data'] = obj.data
dd['meta'] = obj.meta
ddd.append(dd)
cPickle.dump(ddd, codecs.open(
urljoin(TOPDIR, self.id+'.txt'), 'w'))
return self.id
def run(self):
self.queue.put(self.job())
if __name__=='__main__':
processes = []
for i in range(0, num_cores()):
q = Queue()
p = Processor(q, divided_work(), process_num=str(i))
processes.append((p, q))
p.start()
for val in processes:
val[0].join()
key = val[1].get()
storage = urljoin(TOPDIR, key+'.txt')
ddd = cPickle.load(codecs.open(storage , 'r'))
.. unpack ddd process data ...
在run()
方法开始时执行time.sleep(0.001)
。根据我的经验
time.sleep(0.001)
到目前为止还不够长
我也有类似的问题。如果您在队列上调用get()
或put()
时“太早”,似乎会发生这种情况。我猜它初始化得不够快。不完全确定,但我推测这可能与队列使用底层操作系统传递消息的方式有关。在我开始使用BeautifulSoup和lxml之后,它就开始发生在我身上,并影响到完全不相关的代码
我的解决方案有点大,但很简单,而且有效:
import time
def run(self):
error = True
while error:
self.queue.put(self.job())
error = False
except EOFError:
print "EOFError. retrying..."
time.sleep(1)
在我的机器上,它通常在应用程序启动期间重试两次,之后再也不会重试。您需要在发送方和接收方内部执行此操作,因为此错误将在双方发生。
res=self。
看起来不像是错误消息。。这是我的代码挂起的那一行,拼写错误。res=self。不在您显示的代码中。另外,你能再次发布错误消息吗?没有错误消息,我的代码只是挂起。当我按下ctrl-c键时,我可以看到它挂在res=self.\u recv()。在你发布的代码中没有res=self.\u recv()
。谢谢你的回答,我会做的。但你能解释一下你的推理吗?我曾经有过类似的问题,它似乎也适用于我。不幸的是,我没有更令人满意的解释。我会回复结果,顺便说一句,这对我来说有点奇怪,因为我的工作方法需要很长时间,比如5分钟。你认为暂停一毫秒会改变什么吗。奇怪的谢谢你的回复,虽然我不能确定,但是试着找出答案,它可能不起作用,在这种情况下需要更多的调查!哎哟,它还在挂着:\也许是我的逻辑在计算中花了永远的时间