繁体   English   中英

zmq python在multiprocessing.Process而不是threading.Thread时崩溃

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM