Python pyzmq:程序卡住

时间:2016-05-16 09:40:33

标签: python zeromq distributed-system

这是一个使用PUB/SUBpyzmq的简单 multiprocessing 计划。

服务器 PUB 。它每次都会向客户ahah发送 SUB 列表的一部分。

客户 SUB 第一个 .recv_string() 一条消息,然后它将套接字.recv_string() - 处理模式更改为{{ 1}}一个,在 NOBLOCK 循环中。

.Poller()

当我启动该程序时,它只是停留在那里并输出如下:

import logging
import zmq
from multiprocessing import Process

def server_init(port_pub):
  ahah = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  index = 0
  num = 2

  context = zmq.Context()
  socket_pub = context.socket(zmq.PUB)
  socket_pub.bind("tcp://127.0.0.1:%s" % port_pub)

  # socket_rep = context.socket(zmq.REP)
  # socket_rep.bind("tcp://*:%s" % port_rep)

  socket_pub.send_string(' '.join(str(v) for v in ahah[index : index + num - 1]))
  index = index + num

  poller_pub = zmq.Poller()
  poller_pub.register(socket_pub, zmq.POLLOUT)

  should_continue = True
  while should_continue:
    socks = dict(poller_pub.poll())
    if socket_pub in socks and socks[socket_pub] == zmq.POLLOUT and index <= 9:
      socket_pub.send_string(' '.join(str(v) for v in ahah[index : index + num - 1]), zmq.NOBLOCK)
      index = index + num
    else:
      should_continue = False
      poller_pub.unregister(socket_pub)

def client(port_sub):
  context = zmq.Context()
  socket_sub = context.socket(zmq.SUB)
  socket_sub.connect("tcp://127.0.0.1:%s" % port_sub)

  tmp = socket_sub.recv_string()
  process_message(tmp)

  poller_sub = zmq.Poller()
  poller_sub.register(socket_sub, zmq.POLLIN)

  should_continue = True
  while should_continue:
    socks = dict(poller_sub.poll())
    if socket_sub in socks and socks[socket_sub] == zmq.POLLIN:
      tmp = socket_sub.recv_string(zmq.NOBLOCK)
      process_message(tmp)
    else:
      should_continue = False
      poller_pub.unregister(socket_sub)

def process_message(msg):
  print("Processing ... %s" % msg)


if __name__ == '__main__':
  logging.info('starting')
  Process(target=server_init, args=(5566,)).start()
  Process(target=client, args=(5566,)).start()

在按下 $ python test.py 之后:

Ctrl-C

我认为客户至少应$ python test2.py ^CProcess Process-2: Error in atexit._run_exitfuncs: Traceback (most recent call last): File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/popen_fork.py", line 29, in poll pid, sts = os.waitpid(self.pid, flag) KeyboardInterrupt Traceback (most recent call last): File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/process.py", line 254, in _bootstrap self.run() File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/process.py", line 93, in run self._target(*self._args, **self._kwargs) File "test2.py", line 38, in client tmp = socket_sub.recv_string() File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/site-packages/zmq/sugar/socket.py", line 402, in recv_string b = self.recv(flags=flags) File "zmq/backend/cython/socket.pyx", line 674, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:6971) File "zmq/backend/cython/socket.pyx", line 708, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:6763) File "zmq/backend/cython/socket.pyx", line 145, in zmq.backend.cython.socket._recv_copy (zmq/backend/cython/socket.c:1931) File "zmq/backend/cython/checkrc.pxd", line 12, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:7222) KeyboardInterrupt 一个.recv()

但为什么不呢?

1 个答案:

答案 0 :(得分:1)

为什么?

除了其他原因,您的客户端在调用第一个.recv_string()之前忘记订阅任何有意义的内容,因此它会永久挂起阻塞模式接收,而没有任何内容可以满足{{1在收到的邮件上加上 SUB - 过滤,因此没有人会传递给TOPIC - 处理。

只需添加 .recv_string() ,因为socket_sub.setsockopt( "" )默认是默认订阅任何内容(因为没有人能够猜到任何通过TOPIC过滤器的魔法#39;实际情况,所以作为一个悖论,没有似乎是这种意义上的最佳选择。)

接下来还要注意时间安排(ZeroMQ / .bind())灵敏度。

有关详细信息,请不要犹豫下载和阅读神话般的Pieter HINTJENS&#39; book&#34; Code Connected,Volume 1&#34;。