我有一个用 Python 编写的程序,它启动了几个 C++ 二进制文件作为子进程。我正在使用 ZMQ 在两者之间进行通信。 python 类被分解,这样 Thread-A 将数据推送到 ZMQ 套接字中,然后 Thread-B 从不同的 ZMQ 套接字中拉取数据。所以系统的框图可以看成:
线程-A ---port1---> C++ ---port2---> 线程-B
Thread-A 和 Thread-B 是从同一个 Python 类启动的,而 C++ 是一个二进制 w/由启动线程 A 和 B 的同一个 python 类启动,使用 subprocess.Popen(。 ..)——一切都很好。当我尝试将线程的 A 和 B 转换为进程时……东西中断了。当 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 会触发断言正在从不同进程访问上下文的错误。
