Я бы порекомендовал это превосходное прохождение асинцио, которое должно ответить на большинство ваших вопросов.
Цитата из упомянутой статьи в свете вашего кода:
[...] async IO представляет собой однопоточный однопроцессный проект: в нем используется совместная многозадачность, термин, который [...] дает ощущение параллелизма, несмотря на использование одного потока в одном процессе.
Если вы не хотите, чтобы ваша программа блокировала во время обработки (IO) запросов (как указано в вашем вопросе), параллелизма достаточно (и вам не нужна многопоточность)!
Параллельность [...] предполагает, что несколько задач могут запускаться с перекрытием.
Я повторю точный пример из упомянутой статьи, структура которой аналогична вашему примеру:
#!/usr/bin/env python3
# countasync.py
import asyncio
async def count():
print("One")
await asyncio.sleep(1)
print("Two")
async def main():
await asyncio.gather(count(), count(), count())
if __name__ == "__main__":
import time
s = time.perf_counter()
asyncio.run(main())
elapsed = time.perf_counter() - s
print(f"{__file__} executed in {elapsed:0.2f} seconds.")
Это работает следующим образом:
$ python3 countasync.py
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.
Обратите внимание, что в этом примере используется asyncio.gather
для запуска трех count()
процессов неблокирующим образом.Размещение трех await count()
операторов друг за другом не сработает.
Насколько я вижу, это точно , что вы ищете.Как показано, вам не нужно threading
, чтобы достичь этого.