首页 > 解决方案 > 使用线程在 ZeroMQ REQ/REP 模式的服务器端创建许多应答器套接字

问题描述

由于我的工作原因,使用 ZeroMQREQ/REP模式,我决定让服务器的应答器在与主体不同的线程中工作。我将展示的代码总结了这种方法:

import time
import zmq
import threading


def make_work(context):
    socket = context.socket(zmq.REP)
    socket.bind("tcp://*:5555")

    message = socket.recv()
    print("Received request: %s" % message)

    #Do some 'work'
    time.sleep(1)

    #Send reply back to client
    socket.send(b"World")
    socket.close()



 context = zmq.Context()
 thr = None

 while True:

    if not thr or not thr.is_alive():

        thr = threading.Thread(target = make_work, args = (context, ) )
        thr.start()

我修改了 pyzmq 指南的 hello world 示例。所以,我的问题是,当我从 Pieter Hintjens 制作的文档运行 hello world 客户端时,预期的行为是:对于我正在创建的每个线程,我打开的应答器套接字将答案发送给客户端,但是真正的行为是,在第一个线程之后,连接块的两侧。如果我在客户端进行轮询,然后重试发送,则成功,但这不是我想要的。在新线程中,服务器端有可能成功接收吗?

标签: pythonmultithreadingnetworkingzeromq

解决方案


在新线程中,服务器端是否有可能成功接收?

是的。

您的一半代码(客户端仍然不可见)效率非常低。创建+设置+自建基础设施需要一些时间(重新实例化Socket-instance,配置其本地端,要求O / S提供端口.bind(),等待其他人成功检测到存在新的交易对手.connect()并实际上做了一个.connect()设置和协商一个 ling 在那里和回来......),所有这些都只是一个消息和.close()

好吧,如果有人愿意的话。

智能系统可以重复使用资源,而无需为已经支付的费用支付两次费用,次数越少。


另外,您的无限循环“重新安装”线程会产生您从代码中看不到的额外副作用。除了上述所有概述的系统性(但每次调用都重复)延迟之外,还有一个可能永远阻塞的延迟zmq.LINGER- 一个秘密阻塞器。

ZeroMQ API 的早期版本使用默认值zmq.LINGER == -1- 能够无限长地阻塞该.close()方法。更新的版本,肯定是 v4.3-stable,zmq.LINGER默认使用1000 [ms].

无论如何,专业的设计明确地控制实例参数并.setsockopt( zmq.LINGER, 0 )始终无一例外地出于安全目的进行设置。

如果有兴趣,请随时阅读许多其他ZeroMQ 帖子REQ/REP中有关相互死锁的其他无声危险的更多详细信息


推荐阅读