multiprocessing.queue.get()阻止并且不返回

时间:2015-11-05 12:07:24

标签: python-2.7 queue multiprocessing

我正在嵌入式Linux设备上构建一个网络服务器,只有很少的RAM(只有256 MB)。该Web服务器应该能够使用subprocess.check_output发出shell命令,但由于每个check_output似乎需要与父进程消耗的RAM一样多的RAM,我使用多处理来创建第二个进程。当Python仍然没有消耗太多内存时启动。然后,此过程使用multiprocessing.Queue从主进程接收命令,执行它们并使用另一个multiprocessing.Queue返回输出。这曾经起作用,但我似乎有某种竞争条件导致整个事情陷入困境。

这是我复制问题的最小测试用例:

# shwrapper.py
from multiprocessing import Process, Queue

def f(iq,oq):
    oq.put("Ready")
    while True:
        oq.put(iq.get()+" out")

def init():
    iq = Queue()
    oq = Queue()
    p = Process(target=f, args=(iq,oq,))
    p.start()
    print oq.get()
    iq.put("test")
    print(oq.get())
init()

如果我尝试导入这个,我得到这个结果:

>>> import shwrapper
Ready

这里陷入了困境。现在我发出一个KeyboardInterrupt:

^CProcess Process-1:
Traceback (most recent call last):
  File "/usr/lib/python27.zip/multiprocessing/process.py", line 258, in _bootstrap
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "shwrapper2.py", line 17, in <module>
    init()
  File "shwrapper2.py", line 15, in init
    print(oq.get())
  File "/usr/lib/python27.zip/multiprocessing/queues.py", line 117, in get
KeyboardInterrupt
    self.run()
  File "/usr/lib/python27.zip/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "shwrapper2.py", line 6, in f
    oq.put(iq.get()+" out")
  File "/usr/lib/python27.zip/multiprocessing/queues.py", line 117, in get
    res = self._recv()
KeyboardInterrupt

正如你所看到的,它被卡在f的iq.get()中。无论我投入什么,iq-Queue报告总是空的。另一方面,oq-Queue按预期工作。我能在这做什么想法?

我的系统是在PowerPC上运行在Linux 2.6.29.6上的Python 2.7.3。

如果我在Windows计算机上的Python 2.7.10上运行它,一切都会顺利进行。

我知道Python 2.7.3和Linux 2.6.29很古老,但是制造商没有更新的版本,而且系统有点被锁定。

2 个答案:

答案 0 :(得分:2)

我最后使用multiprocessing.queues.SimpleQueue代替multiprocessing.Queue修复了它。根据文档,在这方面应该没有区别,但在源代码中,SimpleQueue使用Lock使其适用于多个进程。

答案 1 :(得分:1)

尝试使用get_notwait代替get。例如:

from multiprocessing import Queue
q = Queue()
try:
    q.get_nowait()
except:
    print("queue is empty")

或者您可以将timeout添加到get方法。例如:

from multiprocessing import Queue
q = Queue()
try:
    q.get(timeout=1)
except:
    print("queue is empty.")