Я бы рекомендовал пойти другим путем: использовать класс 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_
предназначены для вызова с помощью кода syn c (работающего вне потока событий l oop). Те, с префиксом async_
, должны вызываться кодом, выполняющимся в потоке события l oop, независимо от того, являются ли они фактически сопрограммами. (put_nowait
, например, не является сопрограммой, но его все равно следует различать между syn c и asyn c версией.)