问题描述
我创建了一个单独运行的 zmq_forwarder.py
,它将消息从应用程序传递到 sockJS 连接,我目前正在研究 Flask 应用程序如何接收来自sockJS 通过 zmq.我正在粘贴我的 zmq_forwarder.py
的内容.我是 ZMQ 的新手,我不知道为什么每次运行它时,它都会使用 100% 的 CPU 负载.
I created a zmq_forwarder.py
that's run separately and it passes messages from the app to a sockJS connection, and i'm currently working on right now on how a flask app could receive a message from sockJS via zmq. i'm pasting the contents of my zmq_forwarder.py
. im new to ZMQ and i dont know why everytime i run it, it uses 100% CPU load.
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 端口上向其发送数据.
as you can see, i've setup 4 sockets. the app connects to port 5561 to push data to zmq, and port 5562 to receive from zmq (although im still figuring out how to actually set it up to listen for messages sent by zmq). on the other hand, sockjs receives data from zmq on port 5564 and sends data to it on port 5563.
我已经阅读了 zmq.DONTWAIT
使得消息接收异步和非阻塞,所以我添加了它.
i've read the zmq.DONTWAIT
makes receiving of message asynchronous and non-blocking so i added it.
有没有办法改进代码,这样我就不会使 CPU 过载?目标是能够使用 zmq 在 Flask 应用程序和 websocket 之间传递消息.
is there a way to improve the code so that i dont overload the CPU? the goal is to be able to pass messages between the flask app and the websocket using zmq.
推荐答案
你正在一个紧密的循环中轮询你的两个接收器套接字,没有任何阻塞 (zmq.DONTWAIT
),这将不可避免地最大化CPU.
You are polling your two receiver sockets in a tight loop, without any blocking (zmq.DONTWAIT
), which will inevitably max out the CPU.
请注意,ZMQ 支持在单个线程中轮询多个套接字 - 请参阅此答案.我认为您可以在 poller.poll(millis)
中调整超时,以便您的代码仅在有大量传入消息时使用大量 CPU,否则会空闲.
Note that there is some support in ZMQ for polling multiple sockets in a single thread - see this answer. I think you can adjust the timeout in poller.poll(millis)
so that your code only uses lots of CPU if there are lots of incoming messages, and idles otherwise.
您的另一个选择是使用 ZMQ 事件循环来异步响应传入的消息,使用回调.请参阅有关此主题的 PyZMQ 文档,其中改编了以下echo"示例:
Your other option is to use the ZMQ event loop to respond to incoming messages asynchronously, using callbacks. See the PyZMQ documentation on this topic, from which the following "echo" example is adapted:
# 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()
这篇关于如何避免高CPU使用率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!