尽管有完整队列,Python多处理队列get()超时

时间:2017-05-22 06:49:26

标签: python multiprocessing python-multiprocessing

我使用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)))

3 个答案:

答案 0 :(得分:2)

在多处理队列中用作同步消息队列。在您的问题中似乎也是这种情况。然而,这需要的不仅仅是调用get()方法。处理完每个任务后,您需要调用task_done(),以便从队列中删除该元素。

来自文档:

  

Queue.task_done()

     

表示以前排队的任务已完成。由队列使用者线程使用。 对于用于获取任务的每个get(),后续调用task_done()会告知队列任务处理已完成。

     

如果join()当前正在阻止,它将在所有项目都已处理后恢复(这意味着已为每个已放入队列的项目收到task_done()调用)。

在文档中,您还可以找到正确的线程队列使用的代码示例。

如果你的代码应该是这样的

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)))

答案 1 :(得分:0)

您正在捕捉一个过于通用的Exception,并假设它是一个超时错误。

尝试按如下方式修改逻辑:

from Queue import Empty

while (True):
    try:
        item = queue.get(timeout=60)
        break
    except Empty as error:
        logging.info("Writer: Timeout occurred {}".format(str(error)))
        print(queue.qsize())

并查看是否仍然打印了日志。

答案 2 :(得分:0)

切换到基于管理器的队列应有助于解决此问题。

 <script type="text/javascript">
   //Takes user input * passed conversion factor, assigns value to 
     document.getElementById('MED-Tramadol')
   function calculate28(x) 
  {
    var my1 = x;
    var my2 = document.getElementById('r18c2').value;
    //Note: value is parsed as a Float...don't know if it gets converted back to string
    document.getElementById('MED-Tramadol').value = parseFloat(my1) * parseFloat(my2);        
   }

  //same as above
  function calculate29(x) 
   {
    var my1 = x;
    var my2 = document.getElementById('r18c5').value;
    document.getElementById('MED-Sufentanil-intra').value = parseFloat(my1) * parseFloat(my2);        
   }

    //Supposed to combine all values from calculate() function assigned to respective boxes
    function sum() {
    //should collect value from all <input> with name="sum"
      var total = document.getElementsByName('sum').value; 
      var sum = 0;
       for(var i=0; i<total.length; i++)
      {

        totalMED += paredFloat(total[i]).value); 

       }
      document.getElementById('r19c2').value = totalMED;

有关更多详细信息,您可以在此处查看多处理文档:https://docs.python.org/2/library/multiprocessing.html