PyZMQ - 如果没有建立连接,如何终止上下文?

时间:2018-03-20 07:29:30

标签: tcp zeromq pyzmq

当我的套接字尚未连接到绑定地址时,我一直在试图弄清楚如何关闭Context - 实例(或者如果我甚至需要)。这是我的演示代码:

import zmq
import json

data = {}
data['key'] = 'value'
json_data = json.dumps(data)

context = zmq.Context.instance()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")

socket.send_json(data)
socket.close()

print("I get here!")

context.term()

我的预期行为是结束了。我的实际行为是 context.term() 阻止无法消除^ C out。它打印出“我来这里!”在它停止之前,顺便说一句。

编辑结合所选答案的解决方案,这有效:

import zmq
import json

data = {}
data['key'] = 'value'
json_data = json.dumps(data)

context = zmq.Context.instance()
socket = context.socket(zmq.REQ)
socket.setsockopt(zmq.LINGER, 100)
socket.connect("tcp://localhost:5555")

socket.send_json(data)
socket.close()

print("I get here!")

context.term()

1 个答案:

答案 0 :(得分:1)

是的,这是期望的行为。为什么?

ZeroMQ使用 Context -instance作为自主战场单位。它有自己的资源,并在尽可能多的IO线程中运行,因为必须进行性能调整才能产生。

由于这些资源分配和与运输相关的基础设施非常昂贵, .term() -instance方法需要适当注意,而不是损坏仍在等待的玩具在IN / OUT-queues内部,在交付之前。我是否同时提到了基础架构设置和维护加上消息传递机制是异步的,不会发生,根据请求可以完成更少的工作吗?不,他们分开运营"在Context() - 实例引擎下,以尽力而为的方式,在设计中拥有 Zero-of-Zero (包括零 - "保修") -DNA ...

你的代码已经发出消息"那里",所以有一个金蛋,.term() - 调用试图不会损坏,最后杀死Context -instance。

这种行为确实是期望的行为,并且可以针对案例更改它,否则会采取适当的设计保护:

import zmq
import json

print( "Run against ZeroMQ native-API[{0:}]". format( zmq.pyzmq_version_info() ) )    

pass;    aLocalCONTEXT = zmq.Context.instance()
socket = aLocalCONTEXT.socket( zmq.REQ ); socket.connect( "tcp://localhost:5555" )

print( "<aSocket> has LINGER == [{0:}]". format( socket.getsockopt( zmq.LINGER ) )

socket.send_json( json.dumps( { 'key': 'value' } ) ) # MOV. data into Context()
socket.close(); print( "I get here!" )               # N/P to .close() socket


# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ BUT!

aLocalCONTEXT.term()                                 # THE HELL OPENS HERE,
#                                                    # GIVEN LINGER WAS -1
#                                                    # AS .term()-method
#                                                    # MUST WAIT UNTIL ALL MSGs
#                                                    # KNOWN TO BE IN-FLIGHT
#                                                    # GET INDEED DELIVERED, OUCH

即使较新的原生ZeroMQ API版本(4.2+)承诺设置zmq.LINGER默认值,而不是最初注入 -1 == WAIT INDETERMINANTLY TILL DELIVERED, IF NOT FOREVER IN CASE NO PEERS ARE OUT THERE

所以适当的设计方面的关怀确实是公平工程实践的标志:o)