2

我的应用程序的一部分由一个主线程和几个使用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 作为传输协议时,它也可以正常工作。

我发现让它工作的解决方案是:

  1. 使用normal上下文并放弃async/await.
  2. 使用future上下文并ioloop在每个工作人员中运行。
  3. 使用 TCP 作为传输协议。

我的问题是,是否有一个神奇的技巧可以让它工作async/awaitinproc而不必ioloops在工作人员中运行,例如通过future某种方式访问​​上下文non-future

4

0 回答 0