python-3.x - 可视化 asyncio 协程执行
问题描述
我试图了解异步协程是如何从头到尾执行的。可以说我有这个功能
async def statemachine(state):
执行以下操作:
- 读取远程服务器上的值
- 写入远程mysql服务器
- 写入本地redis服务器
- 从远程 mysql 服务器中删除一条记录
- 创建事件并通知协程执行完成
由于 async 暂停执行以给其他协程时间执行,因此执行是否总是从第 1 步开始到第 5 步。
解决方案
协程总是按顺序执行。然而,许多(协同)例程可以(协同)一起操作,同时受到事件循环或各种调度程序的监督。
因此,如果您将所有任务堆叠在一个协程中,例如:
async def statemachine(state):
await read_value_on_remote_server()
await write_to_remote_mysql_server()
await write_to_local_redis_server()
await delete_a_record_from_a_remote_mysql_server()
await create_event_and_notify_coroutine_execution_has_finished()
您statemachine
将一一等待每项任务,直到它们完成。这种情况并没有真正有用,并且与同步代码相比没有任何好处。
异步执行大放异彩的场景是,假设您有一个 Web 应用程序,它statemachine
为每个用户请求安排一个协程。现在,每当用户通过请求访问您的服务器时,都会在事件循环中安排一个新的协程。而且因为事件循环一次只能运行一件事(伪并发),它会让每个协程执行(假设使用循环算法)直到它们挂起,因为它们正在等待一个对象或另一个协程等待另一个对象。
协程挂起的方式是使用 await 语句。这让事件循环知道协程正在等待一个不一定受 CPU 限制的操作。例如网络调用或用户输入。
值得庆幸的是,我们不知道事件循环的实现细节以及它如何设法知道何时应该恢复协程。这通常使用 Python 的 stdlib select
https://docs.python.org/2/library/select.html之类的库来完成。
对于大多数用例,您应该知道协程始终按顺序执行,并且事件循环是通过使用协作方法来管理协程执行的(例如,与典型的 OS 调度程序不同)。
如果你想伪并发运行几个协程,你可以看看asycio.gather
或更正确的asyncio.create_task
. 希望这可以帮助。
推荐阅读
- javascript - 如何从Javascript中的对象获取所有键名
- c# - Swashbuckle 可以为包含对象集合的表单生成正确的 OpenAPI 定义吗?
- java - 请解释这个 JAVA 程序的意外输出
- quantlib - Quantlib FixedRateBond 现金流
- maven - 无法从 Maven 和 NPM 的中央存储库中提取一些包
- reactjs - 在 React Context / Provider 中刷新 REST API
- python - 如何创建 PyTorch 可变张量?
- gdb - GDB:有什么方法可以构造“本地”方便的变量吗?
- r - 有没有办法同时显示许多 R xaringan 幻灯片(如 PowerPoint 幻灯片分类器)
- node.js - 使用 MERN 同时发出运行节点