python zmq 非阻塞线程接收信息

python zmq 非阻塞线程接收信息

zmq 默认的接收函数是阻塞的,这会阻塞同一个进程其他操作。所以我尝试使用轮询监听避免阻塞。

import cloudpickle
import zmq
import time
# pyzmq==23.2.0
# cloudpickle==1.3.0

def send(port=5600):
    context = zmq.Context()
    publisher = context.socket(zmq.PUB)
    publisher.bind('tcp://*:%d' % port)
    while True:
        time.sleep(2)
        topic = 'msg'
        record = {'a': 100, 'b':100}
        # 传输python对象
        publisher.send_serialized(
            record,
            serialize=lambda rec: (topic.encode(), cloudpickle.dumps(rec)),
        )


class Listener:
    """
    zmq非阻塞监控类
    """
    def __init__(self, port=5600, topic='', timeout=0.01):
        """ Constructs the Listener object with a subscriber port
        over which to listen for messages

        :param port: TCP port to listen on
        :param topic: Topic to listen on
        :param timeout: Timeout in seconds to recheck stop flag
        """
        super().__init__()

        self.port = port
        self.topic = topic
        self.context = zmq.Context()

        self.subscriber = self.context.socket(zmq.SUB)
        self.subscriber.setsockopt(zmq.SUBSCRIBE, topic.encode())
        self.subscriber.connect('tcp://localhost:%d' % port)
        # 初始化Poller
        self.poller = zmq.Poller()
        self.poller.register(self.subscriber, zmq.POLLIN)  # 设置为POLLIN则刷新recv
        self.timeout = timeout

    def receive(self, flags=0):
        topic, record = self.subscriber.recv_serialized(
            deserialize=lambda msg: (msg[0].decode(), cloudpickle.loads(msg[1])),
            flags=flags
        )
        return topic, record

    def message_waiting(self):
        """Check if we have a message, wait at most until timeout.
        轮询消息监听,间隔时间self.timeout * 1000,当监听到消息返回一个接收列表
        其他:poller.poll()阻塞,直到有任何套接字上的数据。
        """
        return self.poller.poll(int(self.timeout * 1000))  # poll timeout is in ms

# 监听对象
dataPoller = Listener(5600)
def Listener_func():
    while True:
        print("监听zmq")
        # 隔0.5 秒确认一次是否接收到信息
        time.sleep(0.5)
        # dataPoller.message_waiting() 接收例子[(<zmq.Socket(zmq.SUB) at 0x1ecef4489e8>, 1)]
        if len(dataPoller.message_waiting()) > 0:
            print("监听到消息")
            # 接收信息, 如果接收的是连续数据,也可以再加一个循环判断
            a, b = dataPoller.receive()
            broadcasted_data = {'topic': a, 'record': b}
            print(broadcasted_data)


if __name__ == '__main__':
    import threading
    port = 5600
    t1 = threading.Thread(target=send, args=(port,))
    t2 = threading.Thread(target=Listener_func)
    t1.start()
    t2.start()

在这里插入图片描述

参考

zeroMQ中,zmq.Poller() ,in python 中的用法_没有水杯和雨伞的工科男的博客-CSDN博客_zmq.poller

python的zmq模块 - 简书 (jianshu.com)

随笔记录zmq中的poller()用法_yanfei912的博客-CSDN博客_zmq.poller

Python高级用法之消息队列zmq_达西布鲁斯的博客-CSDN博客_python zmq

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值