我正在嵌入式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很古老,但是制造商没有更新的版本,而且系统有点被锁定。
答案 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.")