02 协程里的任务对象
2022/1/9大约 2 分钟python并发异步编程
02 协程里的任务对象
任务 Task 对象
https://docs.python.org/zh-cn/3/library/asyncio-task.html#coroutines
一般在一个协程A内部,再根据另一个协程B创建任务对象
任务对象一旦创建,协程 B 内的代码就等待调度,调度到开始执行了
await task 可以拿到其包装的协程函数里返回的值
但是比起直接 await 协程B 更灵活,在协程 B 运行的过程中间还可以处理别的事,都处理完了,再 await task
import asyncio
import time
async def nested():
print("nested")
await asyncio.sleep(1)
return 42
async def main():
# Schedule nested() to run soon concurrently
# with "main()".
print(" main 协程开始执行 ")
# create_task(Coroutine) 会把一个协程提交到事件循环中,并会等待调度运行,就是说轮到他就开始执行代码了
task = loop.create_task(nested())
# 异步阻塞,等到结果再往下走
result = await task
print(result)
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print(time.time() - start)
详细看 task 对象
import asyncio
import time
async def nested():
print("nested")
await asyncio.sleep(1)
return 42
async def main():
# Schedule nested() to run soon concurrently
# with "main()".
print(" main 协程开始执行 ")
# create_task(Coroutine) 会把一个协程提交到事件循环中,并会等待调度运行,就是说轮到他就开始执行代码了
task = loop.create_task(nested())
print(task) # <Task pending coro=<nested() running at /Users/xc/code/test_code.py:5>>
await task
print(task) # <Task finished coro=<nested() done, defined at /Users/xc/code/test_code.py:5> result=42>
# 没接受 await task 的返回值不要紧, result() 方法还能取
print(task.result())
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print(time.time() - start)
有 running , done 两个属性,有 cancle() result() 等方法
多个任务
import asyncio
import time
async def nested():
print("nested")
await asyncio.sleep(1)
return 42
async def main():
# Schedule nested() to run soon concurrently
# with "main()".
print(" main 协程开始执行 ")
# 如果想提交多个协程到事件循环
# python3.6
tasks = [
loop.create_task(nested()),
loop.create_task(nested()),
]
# python3.7
# tasks = [
# loop.create_task(nested(), name="1"),
# loop.create_task(nested(), name="2"),
# ]
# "task" can now be used to cancel "nested()", or
# can simply be awaited to wait until it is complete:
await asyncio.sleep(1) # 这里等跟上面已提交的多个协程一起异步阻塞,所以不会浪费时间
# 没其他事要处理了,就异步阻塞一下,等到全部都有结果了,或者到点超时了,就返回
# 返回的是 两个集合 of Future: (done, pending). 超时时间单位是秒
done, pending = await asyncio.wait(tasks, timeout=30)
for task in done:
# 这里的 task 一定是执行完毕的 task,调 result() 方法获取协程函数 nested return 的值
print(task.done(), task.result()) # python3.6
# print(task.get_name(), task.done(), task.result()) # python3.7
for task in pending:
print(task.done())
start = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print(time.time() - start)