我正在使用
Python的多处理模块进行科学并行处理.在我的代码中,我使用了几个工作流程来完成繁重的工作流程和一个将结果保存到磁盘的编写器流程.要写入的数据通过队列从工作进程发送到编写器进程.数据本身相当简单,只包含一个包含文件名的元组和一个包含两个浮点数的列表.经过几个小时的处理后,编写过程经常会卡住.更确切地说是以下代码块
while (True):
try:
item = queue.get(timeout=60)
break
except Exception as error:
logging.info("Writer: Timeout occurred {}".format(str(error)))
永远不会退出循环,我会得到连续的’超时’消息.
我还实现了一个日志记录过程,其中输出队列的状态,即使我得到上面的超时错误消息,对qsize()的调用也会不断返回一个完整队列(在我的情况下大小= 48).
我已经彻底检查了队列对象上的文档,并且找不到为什么get()在队列同时满的情况下返回超时的可能解释.
有任何想法吗?
编辑:
我修改了代码以确保捕获空队列异常:
while (True):
try:
item = queue.get(timeout=60)
break
except Empty as error:
logging.info("Writer: Timeout occurred {}".format(str(error)))
最佳答案 在多处理队列中用作同步消息队列.在您的问题中似乎也是这种情况.然而,这需要的不仅仅是调用get()方法.处理完每个任务后,您需要调用task_done()以便从队列中删除该元素.
来自文档:
Queue.task_done()
Indicate that a formerly enqueued task is complete. Used by queue consumer threads. For each get() used to fetch a task, a subsequent call to task_done() tells the queue that the processing on the task is complete.
If a join() is currently blocking, it will resume when all items have been processed (meaning that a task_done() call was received for every item that had been put() into the queue).
在文档中,您还可以找到正确的线程队列使用的代码示例.
如果您的代码应该是这样的
while (True):
try:
item = queue.get(timeout=60)
if item is None:
break
# call working fuction here
queue.task_done()
except Exception as error:
logging.info("Writer: Timeout occurred {}".format(str(error)))