Связь между асин c задачами и синхронными потоками в python - PullRequest
2 голосов
/ 08 января 2020

Я ищу лучшее решение для связи между асинхронными c задачами и методами / функциями, которые выполняются в исполнителе пула потоков из 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

Есть ли лучший способ?

1 Ответ

2 голосов
/ 08 января 2020

Я бы рекомендовал пойти другим путем: использовать класс 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 версией.)

...