python - 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
类在两个世界之间进行交流。这样做的好处是不必将线程池中的一个槽用于需要很长时间才能完成的操作,例如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
例如,它不是协程,但仍必须区分同步版本和异步版本。)
推荐阅读
- java - 带有 Springboot 2.2 的 MockMvc 给出 406
- javascript - 如何使用 Vanilla Js 拖放存储已放置项目的状态?
- gcc - 这两个链接描述文件部分有什么区别?
- serialization - Inserting data into database returns MismatchedInputException error
- react-native - 如何使 flatlist 增长到填满整个屏幕?
- r - 使用 purrr 使用具有 2 个或更多参数的自定义函数进行映射
- go - How do i make "go get" look in the web rather than on my computer
- python - 用于在给定样本集之间进行贝叶斯优化的 Python 包
- javascript - 创建没有元素的 Stripe 令牌
- php - 在执行编辑或删除功能后通过消息重定向到 Laravel 中的主要操作路线的最佳方式