如果连接到无效的套接字,带有 python 的 Zeromq 挂起 [英] Zeromq with python hangs if connecting to invalid socket

查看:28
本文介绍了如果连接到无效的套接字,带有 python 的 Zeromq 挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我用 pyzmq 连接到一个不存在的套接字,我需要按 CTRL_C 来停止程序.有人可以解释为什么会发生这种情况吗?

If I connect to an inexistent socket with pyzmq I need to hit CTRL_C to stop the program. Could someone explay why this happens?

import zmq

INVALID_ADDR = 'ipc:///tmp/idontexist.socket'

context = zmq.Context()
socket = context.socket(zmq.REQ)

socket.connect(INVALID_ADDR)
socket.send('hello')

poller = zmq.Poller()
poller.register(socket, zmq.POLLIN)
conn = dict(poller.poll(1000))
if conn:
    if conn.get(socket) == zmq.POLLIN:
        print "got result: ", socket.recv(zmq.NOBLOCK)
else:
    print 'got no result'

推荐答案

这个问题也被发布 作为 GitHub 上的 pyzmq 问题.我将在这里解释我的解释(我希望这是合适的,我对 SO 还很陌生):

This question was also posted as a pyzmq Issue on GitHub. I will paraphrase my explanation here (I hope that is appropriate, I am fairly new to SO):

一般规则:如果有疑问,zeromq 程序结束时的挂起是由于 LINGER.

A general rule: When in doubt, hangs at the end of your zeromq program are due to LINGER.

这里的挂起是由 LINGER 套接字选项引起的,并且发生在脚本最后垃圾收集期间调用的 context.term() 方法中.LINGER 行为在 zeromq 文档中描述 ,但把它简单地说,在关闭套接字之后等待队列中的任何待处理消息在丢弃消息之前等待处理超时(以毫秒为单位).默认行为是 LINGER=-1,这意味着永远等待.

The hang here is caused by the LINGER socket option, and happens in the context.term() method called during garbage collection at the very end of the script. The LINGER behavior is described in the zeromq docs, but to put it simply, it is a timeout (in milliseconds) to wait for any pending messages in the queue to be handled after closing the socket before dropping the messages. The default behavior is LINGER=-1, which means to wait forever.

在这种情况下,由于从未启动过任何对等体,因此当套接字尝试关闭时,您尝试发送的hello"消息仍在发送队列中等待.使用 LINGER=-1,ZeroMQ 将等待,直到对等方准备好接收该消息,然后再关闭.如果在此脚本明显挂起时将 RE​​P 套接字绑定到ipc:///tmp/idontexist.socket",则消息将被传递并且脚本将干净地退出.

In this case, since no peer was ever started, the 'hello' message that you tried to send is still waiting in the send queue when the socket tries to close. With LINGER=-1, ZeroMQ will wait until a peer is ready to receive that message before shutting down. If you bind a REP socket to 'ipc:///tmp/idontexist.socket' while this script is apparently hanging, the message will be delivered and the script will finish exiting cleanly.

如果你不希望你的脚本等待(如你已经放弃获得回复的打印语句所示),请将 LINGER 设置为任何非负值(例如 socket.linger = 0),并且 context.term() 将在等待指定的毫秒数后返回.

If you do not want your script to wait (as indicated by your print statements that you have already given up on getting a reply), set LINGER to any non-negative value (e.g. socket.linger = 0), and context.term() will return after waiting the specified number of milliseconds.

我应该注意到,INVALID_ADDR 变量名表明了这样一种理解,即与还没有侦听器的接口的连接是无效的——这是不正确的.zeromq 允许绑定/连接事件以任何顺序发生,如上述行为所示,在发送脚本在 term() 上阻塞时将 RE​​P 套接字绑定到接口.

I should note that the INVALID_ADDR variable name suggests an understanding that connection to an interface that does not yet have a listener is not valid - this is incorrect. zeromq allows bind/connect events to happen in any order, as illustrated by the behavior described above, of binding a REP socket to the interface while the sending script is blocking on term().

这篇关于如果连接到无效的套接字,带有 python 的 Zeromq 挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆