[英]zmq python crashing with multiprocessing.Process but not threading.Thread
我有一个用Python编写的程序,该程序启动了几个C ++二进制文件作为子进程。 我正在使用ZMQ在两者之间进行通信。 python类被分解,这样Thread-A将数据推送到ZMQ套接字,然后Thread-B从另一个ZMQ套接字提取数据。 因此,系统的框图可以看作:
线程A --- port1 ---> C ++ --- port2 ---> Thread-B
Thread-A和Thread-B从同一个Python类开始,而C ++是一个二进制文件,由使用python的subprocess.Popen(...)
启动Thread A和B的同一个python类启动subprocess.Popen(...)
一切正常。 当我尝试将线程的A和B转换为Processes时,东西中断了。 调用ZMQ sock.send()
,它说“资源暂时不可用”。 为了强制执行此异常,我必须放入sock.send(..., zmq.NOBLOCK)
,如果zmq.NOBLOCK
不存在,则发送函数会挂起。 有人可以帮我解释一下吗? 就像我说的那样,当ThreadA和B是线程时,一切正常,但是当我将它们转换为进程时,一切都挂起了。
由于此代码中有很多活动部分,因此,我尝试编写一个测试程序,该程序展示了我在发送数据时遇到的类似问题。 同样,当我运行代码的“线程”版本时,东西可以工作,但是当我处理过程版本时,东西会中断(提示,您可以通过注释/取消注释其中的相应行来在“线程”和“已处理”版本之间切换。下面的代码)。 我正在使用ZMQ 3.2
#!/usr/bin/python
# a simple program to figure out what is going on between threading and
# process for ZMQ
import zmq
import threading
import time
import multiprocessing
class MainClass:
def __init__(self):
port = 11112
s = SenderClass(port)
r = ReceiverClass(port)
r.start()
s.start()
class SenderClass(threading.Thread):
# class SenderClass(multiprocessing.Process):
def __init__(self, port):
self.zmqContext = zmq.Context()
self.pushSocket = self.zmqContext.socket(zmq.PUSH)
self.pushSocket.bind('tcp://*:' + str(port))
threading.Thread.__init__(self)
# multiprocessing.Process.__init__(self)
print 'sender init'
def run(self):
print 'sender running'
for ii in range(0,10):
print 'sent ' + str(ii)
self.pushSocket.send(str(ii))
time.sleep(1)
self.pushSocket.send('KILL')
class ReceiverClass(threading.Thread):
# class ReceiverClass(multiprocessing.Process):
def __init__(self, port):
self.zmqContext = zmq.Context()
self.pullSocket = self.zmqContext.socket(zmq.PULL)
self.pullSocket.connect('tcp://localhost:' + str(port))
threading.Thread.__init__(self)
# multiprocessing.Process.__init__(self)
print 'rx init'
def run(self):
print 'rx running'
while True:
rx = self.pullSocket.recv()
if rx=='KILL':
break;
print 'received = ' + rx
if __name__=='__main__':
M = MainClass()
您应该首先启动bind()
ing套接字,然后再connect()
...
更新:
同样,在启动新的threading.Thread时-可以将上下文创建到父线程中并传递给子线程,但是当使用multiprocessing.Process时,应该在子进程中创建zmq.Context,否则zmq会触发断言错误,正在从其他进程访问上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.