asyncio.shield函数的使用
摘要:整理一下asyncio.shield函数的使用
使用
说到底我不明白asyncio.shield函数到底有什么用,真的可以保护协程函数执行不被取消?未必......只有该协程不能是最后一个被loop循环执行的协程时,才能使用shield函数防止协程被取消......。但是复杂环境我怎么知道协程什么时候被执行....看下面这个例子就知道了。
例子
例子1:可以看到使用asyncio.shield保护task1不被取消,然后使用task1.cancel()取消task1,但是task1依然可以执行。
import asyncio
async def a():
print("a-1执行")
await asyncio.sleep(1)
print("a-2执行")
return 'A'
async def b():
await asyncio.sleep(3)
print("b-1执行")
return 'B'
loop = asyncio.get_event_loop()
task1 = asyncio.shield(a())
task2 = loop.create_task(b())
async def main():
f = asyncio.gather(task1, task2, return_exceptions=True)
task1.cancel()
a = await f
print(a)
loop.run_until_complete(main())
'''
运行结果:
a-1执行
a-2执行
b-1执行
[CancelledError(), 'B']
'''
例子2:把代码的部分改成下面
import asyncio
async def a():
print("a-1执行")
await asyncio.sleep(4)
print("a-2执行")
return 'A'
async def b():
await asyncio.sleep(1)
print("b-1执行")
return 'B'
loop = asyncio.get_event_loop()
task1 = asyncio.shield(a())
task2 = loop.create_task(b())
async def main():
f = asyncio.gather(task1, task2, return_exceptions=True)
task1.cancel()
a = await f
print(a)
loop.run_until_complete(main())
'''
运行结果:
a-1执行
b-1执行
[CancelledError(), 'B']
'''
例子1和例子2做对比,可以发现使用shield函数防止协程被取消时,该协程不能是最后一个被loop循环执行的协程。
原因:懒得去翻源码了,有兴趣自己看实现去。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。