recv_pyobj的行为与Thread to Process不同

时间:2016-09-22 12:16:48

标签: python multithreading sockets subprocess


为了保持性能,我试图一次从6个不同的过程中读取套接字中的数据。我做了一个测试,打开6个线程并从每个线程读取一个套接字,另一个测试打开6个子进程并读取不同的套接字。线程读取工作正常,看起来像这样:

class ZMQServer:
    context = zmq.Context()
    socket = None
    ZMQthread = None

    def __init__(self, port, max_size):
        self.socket = self.context.socket(zmq.SUB)
        self.socket.setsockopt(zmq.SUBSCRIBE, '')
        self.socket.connect("tcp://127.0.0.1:" + str(port))

    def StartAsync(self):
        ZMQthread = threading.Thread(target=self.Start)
        ZMQthread.start()

   def Start(self):
        print "ZMQServer:Wait for next request from client on port: %d" % self.port
        while True:
            print "Running another loop"
            try: 
                message = self.socket.recv_pyobj()
            except: 
                print "ZMQServer:Error receiving messages"

if __name__ == '__main__':
    zmqServers = [None] * 6
    for idx in range (0, 6):
        zmqServers[idx] = ZMQServer(DTypes.PORTS_RECREGISTER[idx], 1024)
        zmqServers[idx].StartAsync()

这将显示:

  

ZMQServer:等待来自客户端的下一个请求:4994
      运行另一个循环
      ZMQServer:等待来自客户端的下一个请求:4995
      运行另一个循环
      ZMQServer:等待来自客户端的下一个请求:4996
      运行另一个循环
      ZMQServer:等待来自客户端的下一个请求:4997
      运行另一个循环
      ZMQServer:等待来自客户端的下一个请求:4998
      运行另一个循环
      ZMQServer:等待来自客户端的下一个请求:4999

重要提示:我收到插件的数据,我发送它 现在,我需要实现相同的行为,但只有线程才使用进程,因此octa核心将使用更多的处理器。代码如下所示:

context = zmq.Context()
def CreateSocket(port):
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, '')
    socket.connect("tcp://127.0.0.1:" + str(port))

def Listen(socket, port):
    print "ZMQServer:Wait for next request from client on port: %d" % port
    while True:
        print "Running another loop"
        try: 
            message = socket.recv_pyobj()
            print "ZMQServer:Received request: %s" % message
        except: 
            print "ZMQServer:Error receiving messages"
            continue

  #I'm trying first only with 1 Process - 1 socket:

   if __name__ == '__main__':
        port = DTypes.PORTS_RECREGISTER[0]
        socket = CreateSocket(port)
        proc = Process(target=Listen, args=(socket, port))
        proc.start()
        proc.join()

输出很奇怪:

  

ZMQServer:等待来自客户端的下一个请求:4994
      运行另一个循环
      ZMQServer:接收消息时出错
      运行另一个循环
      ZMQServer:接收消息时出错
      运行另一个循环
      ZMQServer:接收消息时出错
      ............

非常重要的是,当我发送套接字时,我没有收到套接字上的数据 所以,从我能理解的:
1.方法进入并在每个while循环中更换套接字?
2.或者recv_pyobj不再阻止了?
以前有人经历过吗?有谁知道如何对多进程套接字读取进行更正?
谢谢

1 个答案:

答案 0 :(得分:0)

实际上,问题是因为向进程/线程传递了SOCKET类型参数。看来,在序列化传递给回调方法的数据的幕后,酸洗不能很好地序列化SOCKET参数。
所以,我改了它,所以我不会传递一个套接字参数:

context = zmq.Context()

def ListeToSocket(port):
    socket = context.socket(zmq.SUB)
    socket.setsockopt(zmq.SUBSCRIBE, '')
    socket.connect("tcp://127.0.0.1:" + str(port))
    print "Wait for data on port: %d" % port
    while True:
        try:
            message = socket.recv_pyobj()
            print "PORT:%d Received data: %s" % (port, message)
        except:
            print "PORT:%d: Error receiving messages" % port

if __name__ == '__main__':
    for idx in range(0, DTypes.SOCKET_MAX):
        proc1 = Process(target=ListeToSocket, args=(DTypes.PORTS_RECREGISTER[idx], ))
        proc1.start()