python-asyncio - 工作变量如何与 asyncio 中的任务一起使用?
问题描述
在学习 asyncio 的过程中,我犯了一个错误,将变量“task1”链接了 3 次。
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
print(f"start at {time.strftime('%X')}")
task1 = asyncio.create_task(say_after(1, 'a'))
task1 = asyncio.create_task(say_after(2, 'aba'))
task1 = asyncio.create_task(say_after(3, 'faf'))
await task1
#await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
但是当我运行代码时,我得到了这个输出
start at 19:05:19
a
aba
faf
finished at 19:05:22
为什么它不只打印最后创建的任务?为什么第一个和第二个任务没有清除?
在清晰的python中,如果我这样写:
page = 0
page = 1
page = 2
print(page)
我会得到“2”,因为之前指向对象的链接将从内存中删除。
为什么那里不一样?这个怎么运作?
解决方案
您正在启动三个任务并等待三个任务中最慢的一个完成。
await task1
没有运行任务,它正在等待分配给的第三个任务对象task1
完成。其他两个任务仍然存在于事件循环中并且仍在运行,它们首先完成,因为它们更快。
另一种看待这个问题的方法是稍微修改你的代码。这将按照您的预期开始,然后抛出错误,因为程序在较慢的任务之前完成。
task1 = asyncio.create_task(say_after(3, 'a')) # make slowest
task1 = asyncio.create_task(say_after(2, 'aba'))
task1 = asyncio.create_task(say_after(1, 'faf')) # make fastest
重写你的代码就是完全删除代码,以task1=
明确这await task1
更多地与等待任务完成有关,而与使其运行无关。
asyncio.create_task(say_after(1, 'a'))
asyncio.create_task(say_after(2, 'aba'))
asyncio.create_task(say_after(3, 'faf'))
while len(asyncio.all_tasks()) > 1:
await asyncio.sleep(0.1)
# await task1
更常用的方法是收集对所有任务的引用并等待任务列表完成。
tasks = []
tasks.append(asyncio.create_task(say_after(3, 'a')))
tasks.append(asyncio.create_task(say_after(2, 'aba')))
tasks.append(asyncio.create_task(say_after(1, 'faf')))
await asyncio.gather(*tasks)
推荐阅读
- android - 在android studio应用程序中使用git命令删除所有缓存后,不显示“app”等其他模块
- javascript - 如何将jquery文件与html文件链接?
- php - 创建多租户 / Saas 并在为用户设计数据库时遇到问题
- scala - 在 Gatling 中将多个检查作为变量参数传递
- visual-studio - 如何从 Visual Studio 2019 标题栏中删除“登录”控件?
- android - 如何从 recyclerview 和 sqlite 中删除项目?
- python - Windows-Pyinstaller 错误“无法执行脚本”当应用程序单击时
- php - 如何修复“Apache2 Debian 默认页面”而不是我的网站
- java - 单击步骤指示器上的功能
- matlab - 如何用 mvnpdf 向量化 Matlab 代码?