Асинхронное программирование в python: краткий обзор

Асинхронный мьютекс

Как можно заметить, помимо выделения части из метода , убран . Для стандартного мьютекса блокировка возвращает , который несет информацию о возникшей панике на предыдущих блокировках мьютекса в других потоках. В асинхронном мьютексе блокировка — это футура, разрешающаяся в тип аналогичный . А значит в асинхронном случае информация о панике теряется, просто закрывая критическую секцию при раскрутке стэка. С одной стороны это достаточно удобно, поскольку не возникает взаимных блокировок, с другой достаточно просто получить неконсистентное состояние синхронизируемого объекта.



Другая проблема с асинхронным мьютексом — это поведение при взаимных блокировках. Как я уже упоминал, rust не защищает от них и само собой асинхронный подход не исключение. Однако достаточно важный момент, что отладка в последнем случае существенно сложнее. Взаимная блокировка асинхронного мьютекса блокирует задачу, а не поток. Так что при адекватной нагрузке на процессор можно не заметить заблокированные задачи. При взаимной блокировке в случае с потоками можно заметить, что процесс простаивает, и при подключении отладчиком можно увидеть в трассировке стека блокирующий системный вызов. В случае с асинхронным мьютексом, состояние блокировки хранится во внутренней структуре экзекьютора (или другого крейта) и отследить это состояние уже существенно сложнее.

Ограничение времени жизни


Другая уловка, нежели общее решение, является подход с пересмотром времени жизни . В примере, вызов происходил в конце области видимости, т.е. после . Поскольку переключение между задачами может происходить только в await-точках, все еще возможно использовать объекты в этих рамках. Конкретно для этого примера, будет работать ограничение жизни для прямо перед вызовом асинхронной функции:


На практике, указанный подход работает для многих случаев, тем не менее не для всех. К примеру, критическая секция может быть использована для нескольких операций для обеспечения транзакционности. В таком случае операционная система не может управлять мьютексом, а значит быть использован из стандартной библиотеке, вместо этого он должен быть реализован на основе среды выполнения асинхронного экзекьютора.

Что насчет явных промисов?

прим. перев.: под явными промисами автор подразумевает непосредственно сам синтаксис промисов, а под неявными промисами – синтаксис async/await, т.к. он возвращает промис неявно – не нужно писать основаны на самих промисах и, следовательно, оба варианта полностью совместимы

Мой дорогой друг, разве все эти callback-функции не ужасны? Пусть это будет уроком, чтобы никогда больше не использовать callback-функции…

  • — это метод промиса, который берет его результат и передает его в функцию аргумента (по сути, в callback-функцию…)
  • Вы никогда не сможете использовать результат промиса вне контекста . По сути, .then похож на асинхронный блок, который ожидает результат, а затем передает его в callback-функцию.
  • Помимо метода , в промисах существует еще один метод — . Он нужен для обработки ошибок в промисах. Но я не буду вдаваться в детали, потому что на эту тему уже есть миллиард статей и туториалов.

С этим читают