【问题标题】:PyZMQ - How to terminate a Context if no connection was made?PyZMQ - 如果没有建立连接,如何终止上下文?
【发布时间】:2018-03-20 07:29:30
【问题描述】:

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

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 退出。它打印出“我到了!”在它停止之前,顺便说一句。

编辑结合所选答案的解决方案,这可行:

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()

【问题讨论】:

    标签: tcp zeromq pyzmq


    【解决方案1】:

    是的,这是理想的行为。为什么?

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

    由于这些资源分配和与运输相关的基础设施是“昂贵的”,.term()-instance 方法会采取适当的措施,不会损坏仍在 IN/OUT 队列中等待的玩具,在交付之前。我有没有提到基础设施设置和维护以及消息传递机制都是异步的并且不会发生,根据请求允许完成的越少?不,它们在 Context()-instance 引擎盖下“单独”运行,以尽力而为的方式,在设计中具有 Zen-of-Zero(包括零“保修”) -DNA...

    您的代码已经在“那里”放置了一条消息,所以有一个金蛋,.term()-call 试图不破坏,然后最终杀死 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)

    【讨论】:

    • 谢谢! Linger 正是我所需要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2019-12-24
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多