【问题标题】:How to avoid high cpu usage?如何避免高cpu使用率?
【发布时间】:2014-03-23 00:45:34
【问题描述】:

我创建了一个单独运行的zmq_forwarder.py,它将消息从应用程序传递到 sockJS 连接,我目前正在研究烧瓶应用程序如何通过 zmq 从 sockJS 接收消息。我正在粘贴我的zmq_forwarder.py 的内容。我是 ZMQ 新手,我不知道为什么每次运行它时,它都会占用 100% 的 CPU 负载。

import zmq

# Prepare our context and sockets
context = zmq.Context()

receiver_from_server = context.socket(zmq.PULL)
receiver_from_server.bind("tcp://*:5561")

forwarder_to_server = context.socket(zmq.PUSH)
forwarder_to_server.bind("tcp://*:5562")

receiver_from_websocket = context.socket(zmq.PULL)
receiver_from_websocket.bind("tcp://*:5563")

forwarder_to_websocket = context.socket(zmq.PUSH)
forwarder_to_websocket.bind("tcp://*:5564")

# Process messages from both sockets
# We prioritize traffic from the server
while True:

    # forward messages from the server
    while True:
        try:
            message = receiver_from_server.recv(zmq.DONTWAIT)
        except zmq.Again:
            break

        print "Received from server: ", message
        forwarder_to_websocket.send_string(message)

    # forward messages from the websocket
    while True:
        try:
            message = receiver_from_websocket.recv(zmq.DONTWAIT)
        except zmq.Again:
            break

        print "Received from websocket: ", message
        forwarder_to_server.send_string(message)

如您所见,我设置了 4 个套接字。该应用程序连接到端口 5561 以将数据推送到 zmq,并连接到端口 5562 以从 zmq 接收(尽管我仍在弄清楚如何实际设置它以侦听 zmq 发送的消息)。另一方面,sockjs 在 5564 端口从 zmq 接收数据,并在 5563 端口向它发送数据。

我已阅读 zmq.DONTWAIT 使接收消息异步且非阻塞,因此我添加了它。

有没有办法改进代码,以免 CPU 过载?目标是能够使用 zmq 在烧瓶应用程序和 websocket 之间传递消息。

【问题讨论】:

    标签: python flask zeromq sockjs pyzmq


    【解决方案1】:

    您正在一个紧密的循环中轮询您的两个接收器套接字,没有任何阻塞 (zmq.DONTWAIT),这将不可避免地耗尽 CPU。

    请注意,ZMQ 支持在单个线程中轮询多个套接字 - 请参阅 this answer。我认为您可以在 poller.poll(millis) 中调整超时,这样您的代码仅在有大量传入消息时才使用大量 CPU,否则空闲。

    您的另一个选择是使用 ZMQ 事件循环来异步响应传入消息,使用回调。请参阅有关此主题的PyZMQ documentation,从中改编了以下“回声”示例:

    # set up the socket, and a stream wrapped around the socket
    s = ctx.socket(zmq.REP)
    s.bind('tcp://localhost:12345')
    stream = ZMQStream(s)
    
    # Define a callback to handle incoming messages
    def echo(msg):
        # in this case, just echo the message back again
        stream.send_multipart(msg)
    
    # register the callback
    stream.on_recv(echo)
    
    # start the ioloop to start waiting for messages
    ioloop.IOLoop.instance().start()
    

    【讨论】:

    • 感谢您的回复,但您能否详细说明“您的另一个选择是使用 ZMQ 事件循环通过回调异步响应传入消息。”?
    • 没问题 - 我已经添加了链接和示例。
    • 嗯...我实际上正在构建一个烧瓶+龙卷风应用程序。为了通过 zmq 将消息从应用程序传递到 sockjs 连接,我必须单独运行 zmq 脚本。已经在查看您共享的链接。希望我能够在龙卷风之上运行 zmq 脚本。我一定会让你知道情况如何。感谢您的帮助!
    • 非常感谢您的出现并回答了我的问题。它解决了我的主要问题!首先是我的应用程序如何收听消息的问题已经解决!其次,现在可以删除我创建的转发器脚本,因为 websocket 和应用程序现在可以直接相互通信!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-02-28
    • 2020-02-13
    • 1970-01-01
    • 2021-12-09
    • 2014-07-16
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多