繁体   English   中英

python中异步任务和同步线程之间的通信

[英]Communication between async tasks and synchronous threads in python

我正在寻找在来自 concurrent.futures 的线程池执行程序中运行的异步任务和方法/函数之间通信的最佳解决方案。 在以前的同步项目中,我会使用queue.Queue类。 我假设任何方法都应该是线程安全的,因此asyncio.queue将不起作用。

我见过人们扩展queue.Queue类来执行以下操作:

class async_queue(Queue):
  async def aput(self, item):
    self.put_nowait(item)

  async def aget(self):
    resp = await asyncio.get_event_loop().run_in_executor( None, self.get )
    return resp

有没有更好的办法?

我建议asyncio.Queue :使用asyncio.Queue类在两个世界之间进行通信。 这样做的好处是不必在线程池中花费一个槽来处理需要很长时间才能完成的操作,例如get()

下面是一个例子:

class Queue:
    def __init__(self):
        self._loop = asyncio.get_running_loop()
        self._queue = asyncio.Queue()

    def sync_put_nowait(self, item):
        self._loop.call_soon(self._queue.put_nowait, item)

    def sync_put(self, item):
        asyncio.run_coroutine_threadsafe(self._queue.put(item), self._loop).result()

    def sync_get(self):
        return asyncio.run_coroutine_threadsafe(self._queue.get(item), self._loop).result()

    def async_put_nowait(self, item):
        self._queue.put_nowait(item)

    async def async_put(self, item):
        await self._queue.put(item)

    async def async_get(self):
        return await self._queue.get()

sync_为前缀的方法旨在由同步代码(在事件循环线程之外运行)调用。 async_为前缀的将被在事件循环线程中运行的代码调用,无论它们是否实际上是协程。 (例如put_nowait不是协程,但它仍然必须区分同步和异步版本。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM