我的应用程序的一部分由一个主线程和几个使用pyzmq
套接字将其结果发送到主线程的工作线程组成。主线程正在运行 atornado IOloop
并使用async
函数来读取使用 a 创建的各种套接字类型上的传入数据future.context
。
出于性能原因,我想使用该inproc
协议。但是inproc
,仅当主线程和工作线程共享相同的上下文时才有效。另一方面,这将要求每个工作线程都需要运行 a tornado IOloop
,我认为这对于简单的工作人员来说有点矫枉过正。
一个最小的例子来说明这个问题:
import time
from threading import Thread
import zmq
from zmq.eventloop.future import Context as FutureContext
import tornado.ioloop
def worker(ctx):
socket = ctx.socket(zmq.PUSH)
socket.bind('inproc://worker')
while True:
# Do some work
time.sleep(2)
socket.send_pyobj("Work done")
async def mainLoop(ctx):
socket = ctx.socket(zmq.PULL)
socket.connect('inproc://worker')
while True:
#print(socket.recv_pyobj())
print(await socket.recv_pyobj())
normalCtx = zmq.Context()
futureCtx = FutureContext()
t = Thread(target=worker, kwargs=dict(ctx=normalCtx))
t.start()
# wait for bind to be effective
time.sleep(4)
io_loop = tornado.ioloop.IOLoop.current()
io_loop.spawn_callback(mainLoop, ctx=futureCtx)
io_loop.start()
在示例中,PULL
套接字不会接收消息,因为它是在与工作套接字不同的上下文中发出的。normalCtx
如果我在两个线程中使用(删除await
),该示例工作正常。当使用 TCP 作为传输协议时,它也可以正常工作。
我发现让它工作的解决方案是:
- 使用
normal
上下文并放弃async/await
. - 使用
future
上下文并ioloop
在每个工作人员中运行。 - 使用 TCP 作为传输协议。
我的问题是,是否有一个神奇的技巧可以让它工作async/await
,inproc
而不必ioloops
在工作人员中运行,例如通过future
某种方式访问上下文non-future
?