2016-04-01 54 views
2

在python2.7中,multiprocessing.Queue从函数内部初始化时会抛出一个错误的错误。我提供了一个重现问题的最小例子。多处理损坏的管道错误.Queue

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import multiprocessing 

def main(): 
    q = multiprocessing.Queue() 
    for i in range(10): 
     q.put(i) 

if __name__ == "__main__": 
    main() 

抛出下面的破管错误

Traceback (most recent call last): 
File "/usr/lib64/python2.7/multiprocessing/queues.py", line 268, in _feed 
send(obj) 
IOError: [Errno 32] Broken pipe 

Process finished with exit code 0 

我无法破译原因。如果我们不能从函数内部填充Queue对象,那肯定会很奇怪。

回答

3

这里发生的是当您拨打main()时,它创建Queue,放入10个对象并结束该函数,垃圾收集其所有内部变量和对象,包括Queue。 但是你得到这个错误,因为你仍然试图发送Queue中的最后一个数字。

“当一个进程首先将在队列中的进料器线程 开始从缓冲器到所述管传送对象项目”:

从文档 documentation

作为put()在另一个线程中取得,但并不阻止脚本的执行,并允许在完成队列操作之前结束main()功能。

试试这个:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import multiprocessing 
import time 
def main(): 
    q = multiprocessing.Queue() 
    for i in range(10): 
     print i 
     q.put(i) 
    time.sleep(0.1) # Just enough to let the Queue finish 

if __name__ == "__main__": 
    main() 

应该有办法join队列或块执行,直到目标被放在Queue,你应该采取文档中看看。

+0

精彩的回答。我要给另一个说明,在python3中这不会发生。 – hAcKnRoCk

0

延迟使用time.sleep(0.1)按照@HarryPotFleur的建议,解决了这个问题。但是,我用python3测试了代码,并且在python3中根本没有发生管道问题。我认为这被报告为一个错误,后来得到修复。

+0

这是**不正确**,它不会发生在python3中。还有什么更多 'time.sleep(0.1)'没有解决!这只是为了理解! –

1

当启动Queue.put()时,启动隐式线程将数据传递到队列。同时,主应用程序结束,数据没有结束站(队列对象被垃圾收集)。

我想试试这个:

from multiprocessing import Queue 

def main(): 
    q = Queue() 
    for i in range(10): 
     print i 
     q.put(i) 
    q.close() 
    q.join_thread() 

if __name__ == "__main__": 
    main() 

join_thread()保证,缓冲区中的所有数据已被刷新。 close()必须先拨打join_thread()

相关问题