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

标签 python python-asyncio

我正在寻找在来自 concurrent.futures 的线程池执行程序中运行的异步任务和方法/函数之间通信的最佳解决方案。在之前的同步项目中,我会使用 queue.Queue类(class)。我假设任何方法都应该是线程安全的,因此 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类在两个世界之间进行交流。这样做的好处是不必在线程池中花费一个槽来处理需要很长时间才能完成的操作,例如 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 不是协程,但它仍然必须区分同步和异步版本。)

关于python - python中异步任务和同步线程之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59650243/

相关文章:

python - 使用 Python 在 Windows 中执行文件

python - Kivy 音频搜索无法正常工作

python - await 如何在协程链接期间将控制权交还给事件循环?

python - 使用 AsyncIOMainLoop 测试 Tornado 应用程序时出现 AssertionError "assert not IOLoop.initialized()"

python - numpy vstack 后浮点值错误

python - 在 python 中向下舍入到下一个 1000

python - 异常 "There is no current event loop in thread ' MainThread'“在运行新循环时

python - Django `python manage.py runserver` 不支持 asyncio&aiohttp

python - 如果生成器表达式不是唯一参数,则必须用括号括起来

无时间漂移的Python异步生成器函数