[英]running a 2nd zmq.eventloop.ioloop
I want to create a PyZMQ eventloop in a background thread, and have it work correctly with both standalone Python scripts and IPython scripts. 我想在后台线程中创建一个PyZMQ事件循环,并使其与独立的Python脚本和IPython脚本均能正常工作。 (IPython uses PyZMQ eventloops located in the main thread, so this is causing me problems and why I want to start a private ioloop in a background thread.)
(IPython使用位于主线程中的PyZMQ事件循环,因此这导致了我的问题,以及为什么要在后台线程中启动私有ioloop。)
I want to run code in Thread A while having the PyZMQ eventloop handle received data from a socket in Thread B. There are times in Thread A where I will need to wait for an event set in Thread B. 我希望在PyZMQ事件循环句柄从线程B中的套接字接收数据的同时在线程A中运行代码。在线程A中,有时需要等待线程B中设置的事件。
How can I get this to work? 我该如何工作? There seems to be something wrong if I try in IPython:
如果我在IPython中尝试,似乎出了点问题:
from zmq.eventloop import ioloop
import threading
class IOBackgroundLoop(object):
def __init__(self):
self._loop = None
self._thread = threading.Thread(target=self.run)
self._thread.daemon = True
self._started = threading.Event()
@property
def loop(self):
return self._loop
def run(self):
self._loop = ioloop.IOLoop()
self._loop.initialize()
self._loop.make_current()
self._started.set()
self._loop.start()
def start(self):
self._thread.start()
self._started.wait()
bkloop = IOBackgroundLoop()
bkloop.start()
for loop in [bkloop.loop, ioloop.IOLoop.instance()]:
print "%s running: %s" % (loop, loop._running)
This prints out two separate instances of IOLoop, but if I go to use it, it doesn't seem to work. 这将打印出两个单独的IOLoop实例,但是如果我要使用它,它似乎将无法工作。 I can't think of a small example program to demonstrate this;
我想不出一个小的示例程序来演示这一点。 I've tried with a timeout function:
我尝试了超时功能:
import time
def print_timestamp(key):
print "%s: %s" % (time.time(), key)
for loop in [bkloop.loop, ioloop.IOLoop.instance()]:
loop.add_timeout(bkloop.loop.time() + 1.0, lambda: print_timestamp("hi from %s" % loop))
print_timestamp("here")
time.sleep(2.0)
print_timestamp("there")
and I get this as a result (no "hi": 结果我得到了(没有“嗨”:
1412889057.68: here
1412889059.68: there
1412889059.68: here
1412889061.68: there
Then when I hit another shift+Enter, I get 然后,当我按下另一个Shift + Enter时,我得到
1412889061.68: hi from <zmq.eventloop.ioloop.ZMQIOLoop object at 0x000000000467E4E0>
which is the IOLoop object from the main thread, but my private instance IOLoop never prints hi. 这是主线程中的IOLoop对象,但是我的私有实例IOLoop从不打印嗨。
What could I be doing wrong? 我可能做错了什么?
Argh, I just noticed this in the tornado docs: 啊,我只是在龙卷风文档中注意到了这一点:
Note that it is not safe to call
add_timeout
from other threads.请注意,从其他线程调用
add_timeout
是不安全的。 Instead, you must useadd_callback
to transfer control to theIOLoop
's thread, and then calladd_timeout
from there.相反,您必须使用
add_callback
将控制权转移到IOLoop
的线程,然后从那里调用add_timeout
。
It also appears as though the zmq.eventloop.zmqstream
needs to be setup in the same thread as the ioloop for it to work properly. 似乎
zmq.eventloop.zmqstream
需要在与ioloop相同的线程中进行设置才能正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.