Как Spyder запускает событие asyncio l oop в фоновом режиме в том же потоке (или делает это?) - PullRequest
1 голос
/ 14 апреля 2020

Я изучаю модуль / функциональность asyncio уже несколько дней, потому что хочу использовать его для частей своего приложения, связанных с вводом-выводом, и думаю, что сейчас у меня есть разумное понимание того, как оно работает или, по крайней мере, мне кажется, что я понял следующее:

  1. Только одно асинхронное событие l oop может выполняться в одном потоке в любой момент времени.
  2. Как только все установлено up и ready к go l oop .run_forever () или l oop .run_until_complete () вызывается для запуска l oop, и этот вызов блокирует поток навсегда или до тех пор, пока l oop не получит завершено, ie. никакой код syn c не может (или должен) выполняться параллельно с событием-l oop в том же потоке.
  3. Если вам нужно запустить блокировку / недетерминированность c syn c код внутри события l oop, тогда вы должны запустить его внутри «Исполнителя», который (если я правильно понимаю) как бы встраивает поток или пул процессов в событие l oop и запускает там код (в своем собственный новый поток или процесс?)
  4. Разработчики python никогда не предполагали, что асин c код и син c код будут частью одного приложения, потому что я не могу найти абсолютно НИКАКИХ ссылок, объясняющих, как лучше всего реализовать межпотоковую / межсинхронную / асинхронную c кодовую коммуникацию.
  5. Asyncio не была написана для людей.

Учитывая вышесказанные соображения, я много думал о Как запустить мой асин c код в фоновом режиме, выполняя другую (syn c) работу на переднем плане, я также много раз искал в Google и нашел много людей с такими же проблемами. но не так много людей, у которых были хорошие решения, и не те решения, которыми я был доволен.

Так что теперь мой вопрос таков; Как Spyder IDE делает это ???

Я использую Spyder IDE и обнаружил, что Spyder запускает свое собственное событие asyncio l oop, и не только это, вы можете определить и запустить asyn c функционирует непосредственно внутри интерактивной python консоли, просто выполняя:

In [1]: async def my_printer():
   ...:     print('hello world')
   ...:
In [2]: asyncio.run_coroutine_threadsafe(my_printer(), asyncio.get_event_loop())
hello world

Поэтому я подумал: «Интересно, в каком потоке фактически выполняется код, который я печатаю в терминале Spyder», поэтому я попытался:

In [3]: import threading
In [4]: threading.current_thread()
<_MainThread(MainThread, started 9756)>

.. И тогда мое замешательство стало еще больше, когда я попытался;

In [5]: async def get_thread():
   ...:     return threading.current_thread()
   ...:
In [6]: res = asyncio.run_coroutine_threadsafe(get_thread(), asyncio.get_event_loop())
In [7]: res.result()
<_MainThread(MainThread, started 9756)>

Какого черта здесь происходит?

Я не понимаю, как Spyder может запускать событие asyncio l oop в главном потоке, в то же время позволяя мне запускать синхронный код в том же потоке. Мое понимание неверно / я что-то упускаю из-за того, как работает asyncio? или Spyder использует какой-то злой взлом за кулисами, который заставляет его работать?

Я в основном заинтересован в этом, потому что надеюсь, что это поможет мне понять, как код syn c и asyn c могут работать вместе, и потому что это может способствовать моему пониманию asyncio.

...