我正在用Python 3.7编写一个Tornado Web服务器,以显示multiprocessing
库运行的进程的状态。
以下代码有效,但是我希望能够使用Tornado的内置库而不是在线程库中进行入侵。在queue.get
期间,我一直想不出如何在不阻止龙卷风的情况下进行操作。我认为正确的解决方案是在某种将来包装get
调用。我已经尝试了几个小时,但还没有弄清楚该怎么做。
在我的多处理脚本中:
class ProcessToMonitor(multiprocessing.Process)
def __init__(self):
multiprocessing.Process.__init__(self)
self.queue = multiprocessing.Queue()
def run():
while True:
# do stuff
self.queue.put(value)
然后,以我的龙卷风脚本
class MyWebSocket(tornado.websocket.WebSocketHandler):
connections = set()
def open(self):
self.connections.add(self)
def close(self):
self.connections.remove(self)
@classmethod
def emit(self, message):
[client.write_message(message) for client in self.connections]
def worker():
ptm = ProcessToMonitor()
ptm.start()
while True:
message = ptm.queue.get()
MyWebSocket.emit(message)
if __name__ == '__main__':
app = tornado.web.Application([
(r'/', MainHandler), # Not shown
(r'/websocket', MyWebSocket)
])
app.listen(8888)
threading.Thread(target=worker)
ioloop = tornado.ioloop.IOLoop.current()
ioloop.start()
答案 0 :(得分:1)
queue.get
不是阻止功能,它只是等待队列中有一个项目,以防队列为空。从您的代码中可以看出,queue.get
非常适合您在while循环内使用的情况。
我认为您可能未正确使用它。您必须使worker
函数成为协程(async
/ await
语法):
async def worker():
...
while True:
message = await queue.get()
...
但是,如果您不想等待某个项目而想立即进行,则可以选择queue.get_nowait
。
这里要注意的一件事是,如果队列为空,queue.get_nowait
将引发一个名为QueueEmpty
的异常。因此,您需要处理该异常。
示例:
while True:
try:
message = queue.get_nowait()
except QueueEmpty:
# wait for some time before
# next iteration
# otherwise this loop will
# keep running for no reason
MyWebSocket.emit(message)
如您所见,如果队列为空,则必须使用while循环暂停一段时间,以防止它淹没系统。
那么为什么不首先使用queue.get
?