在python中,有3种主要类型的可蜡对象:协同、任务和未来。
我可以await一个协同线,也可以一个tasks。
等待一条协同线
import asyncio
async def nested():
return 42
async def main():
print(await nested()) # will print "42".
asyncio.run(main())等待一项任务
import asyncio
async def nested():
return 42
async def main():
task = asyncio.create_task(nested())
await task
asyncio.run(main())首先,将协同线包装在任务中的价值是什么?看上去他们也是这么做的。
我什么时候需要使用任务和协同线?
发布于 2021-04-08 11:34:09
Coroutine只是在当前可接受的上下文中运行的函数。它可以代表调用方(调用await的人)向事件循环提供执行。想象一下允许暂停它的线程的函数。您可以从另一个方面调用一个协同线,但它们仍然共享同一个线程。
另一方面,任务会立即将单独的作业发布到事件循环中。任务本身就是该任务的句柄。您可以await一个任务,但是它可以在“并行”中自己运行--在单线程上下文中,这意味着任务可以在其他josb屈服时运行(例如,等待I/O)。任务甚至可以在调用await之前完成。
示例没有任务:
job_1 = sleep(5)
job_2 = sleep(2)
# will sleep for 5 seconds
await job_1
# will sleep for another 2 seconds
await job_2任务示例:
job_1 = sleep(5)
job_2 = asyncio.create_task(sleep(2))
# will sleep for 5 seconds
await job_1
# by this time, job_2 is complete
# because previous job has yielded at some point, allowing other jobs to run
# thus await takes no time
await job_2发布于 2021-04-08 10:59:42
在这种情况下,没有真正的区别:通过等待协同线,它将被安排为它的一部分任务的一部分。然而,这意味着它是由其父级驱动的。
通过在任务中包装一个协同线,它可以在事件循环中独立地进行调度,这意味着它不再由包含的任务驱动(它有自己的生命周期),并且可以更丰富地与它交互(例如取消或添加回调)。
想一想“函数”与“线程”,真的。coroutine只是一个可以挂起的函数(如果它在等待东西),但它仍然只存在于调用者的词法和动态上下文中。任务从上下文中解脱出来,它使包装的协同线过自己的生活,就像线程使包装的函数(目标)过自己的生活一样。
发布于 2021-04-08 10:55:00
创建一个Task会将传递的协同线安排在事件循环上运行。您可以使用Task取消基础协同线。
https://stackoverflow.com/questions/67002349
复制相似问题