事件循环上计划的任务的执行顺序 (Python 3.10)
我仍在学习 python 3.10 中的 asyncio 模块。下面是我编写的代码,试图了解如何在事件循环上将协程作为任务运行。我得到的输出与我的预期不同。请帮助我理解我做错了什么或者是否有什么我误解的地方。
import asyncio
async def f(x):
try:
print(f"Inside f({x})...")
await asyncio.sleep(x)
print(f'slept for {x} seconds!!')
return x
except asyncio.CancelledError: # Execute this part only when the task is cancelled.
print(f'Cancelled({x})')
async def main():
loop = asyncio.get_running_loop()
task1 = loop.create_task(f(1), name="task1")
task2 = loop.create_task(f(2), name="task2")
task3 = loop.create_task(f(3), name="task3")
print(task1.done())
print(task2.done())
print(task3.done())
asyncio.run(main())
输出:
False False False 在 f(1) 内... 在 f(2) 内... 在 f(3) 内... 已取消(3) 已取消(1) 已取消(2)
我希望此代码在 print(task3.done())
之后立即退出 main() ,并且仅运行协程函数 f 的异常处理部分(x),但事件循环在实际退出之前恰好运行 f(1)、f(2) 和 f(3) 的功能一次。 我的疑问是
- 为什么事件循环上的所有任务在取消之前都会运行一次?
- 执行顺序是什么(如果有的话,是固定的还是随机的?)
编辑: 我首先尝试使用 task1 = asyncio.create_task(f(1), name = "task1")
。然后我使用了loop.create_task()。两者都给出相同的输出(我猜这是预期的)。
I am still learning the asyncio module in python 3.10. Below is a code I wrote trying to understand how to run coroutines as tasks on an event loop. the output I am getting is different from what I expected. Please help me understand what I am doing wrong or if there is something I misunderstood.
import asyncio
async def f(x):
try:
print(f"Inside f({x})...")
await asyncio.sleep(x)
print(f'slept for {x} seconds!!')
return x
except asyncio.CancelledError: # Execute this part only when the task is cancelled.
print(f'Cancelled({x})')
async def main():
loop = asyncio.get_running_loop()
task1 = loop.create_task(f(1), name="task1")
task2 = loop.create_task(f(2), name="task2")
task3 = loop.create_task(f(3), name="task3")
print(task1.done())
print(task2.done())
print(task3.done())
asyncio.run(main())
Output:
False False False Inside f(1)... Inside f(2)... Inside f(3)...
Cancelled(3) Cancelled(1) Cancelled(2)
I expect this code to exit main() immediately after print(task3.done())
and only run the exception handling part of the coroutine function f(x), but the event loop runs the functionalities of f(1), f(2) and f(3) exactly one time before actually exiting.
My doubts are
- Why do all the tasks on the event loop run once before getting cancelled?
- What is the execution order (if there is any, is it fixed or random?)
Edit:
I first tried using task1 = asyncio.create_task(f(1), name = "task1")
. Then I used loop.create_task()
. Both give same output(which is to be expected I guess).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你应该将“task1 = loop.create_task(f(1), name="task1")”行更改为“task1 = asyncio.create_task(f(1), name="task1")”
I think you should change the line "task1 = loop.create_task(f(1), name="task1")" to be "task1 = asyncio.create_task(f(1), name="task1")"
您的程序在异步任务完成之前就已完成,因此它们都将被取消。对
done()
的调用只是打印出它们还没有完成。如果您想让任务有机会完成,除了前面的答案之外,您还需要添加
await(task1)
等。或者只是await asyncio.gather(task1, task2, task3)
在一次调用中等待所有这些任务。Your program is finishing before your asynchronous tasks are done, so they are all being cancelled. The call to
done()
just prints that they're not done.You need to add
await(task1)
, etc. in addition to the previous answer if you want to give your tasks the chance to finish. Or justawait asyncio.gather(task1, task2, task3)
to wait for all of them in one call.