线程本地 pyzmq ioloop

Thread local pyzmq ioloop

我想知道是否有办法在 pyzmq 中有一个线程本地 ioloop。代码中的注释说 (https://github.com/zeromq/pyzmq/blob/master/zmq/eventloop/minitornado/ioloop.py line 172):

In general you should use IOLoop.current as the default when constructing an asynchronous object, and use IOLoop.instance when you mean to communicate to the main thread from a different one.

据此,我假设使用 .current 我应该能够创建线程本地 ioloop,我可以 start/stop 独立于主线程 ioloop。

奇怪的是,这不是我观察到的行为(我在本地线程中使用 .current,但在此循环上执行 .stop 也会停止主线程循环)。而且,这个简单的测试代码:

import threading
from zmq.eventloop import ioloop

loop = ioloop.IOLoop.current()
print 'main id(loop):', id(loop)

class w(threading.Thread):
    def __init__(self, loop=None):
        super(w, self).__init__()

        self.loop = loop or ioloop.IOLoop.current()

        print 'w.__init__ id(loop):', id(self.loop)

    def run(self):
        print 'w.__run__ id(loop):', id(self.loop)
        print 'current:', id(ioloop.IOLoop.current())


w(loop).start()

为两个循环打印相同的 ID:

main id(loop): 33576144
w.__init__ id(loop): 33576144
w.__run__ id(loop): 33576144
current: 33576144

我很乐意了解我错过了什么。

亚历克斯

IOLoop.current() 由于历史原因有一些怪癖。如果存在,它将引用线程本地事件循环,但它不会创建一个,而是退回到单例(主线程)循环。

解决方案是在 w.__init__() (self.loop = ioloop.IOLoop()) 中创建一个新循环并使其在 w.run() 中成为当前循环 (self.loop.make_current()loop.start() 将调用make_current() 给你)。