0%

python | task

task 就是任务,即可以向事件循环中添加或者注册任务,等待事件循环执行。

task 通过 asyncio.create_task() 「python3.7 引入」 创建,也可以通过

1
2
loop = asyncio.get_event_loop()
loop.create_task()

创建,还可以通过 asyncio.ensure_future() 「python3.7 之前的用法」创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import asyncio


async def run0():
await asyncio.sleep(1)
print("run0")


async def main():
task1 = asyncio.create_task(run0())
task2 = asyncio.create_task(run0())

r1 = await task1
r2 = await task2

print(r1, r2)


asyncio.run(main())

优化成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio


async def run0():
await asyncio.sleep(1)
print("run0")


async def main():
tasks = [asyncio.create_task(run0()),
asyncio.create_task(run0())]

done, pending = await asyncio.wait(tasks)
print(done)


asyncio.run(main())

输出

1
2
3
run0
run0
{<Task finished coro=<run0() done, defined at /Users/licong/python/chengzi/baojia/info/test.py:4> result=None>, <Task finished coro=<run0() done, defined at /Users/licong/python/chengzi/baojia/info/test.py:4> result=None>}

先记住一点,事件循环是在

asyncio.run(main())

创建的,如果改成

1
2
3
4
5
6
7
8
9
10
11
import asyncio


async def run0():
await asyncio.sleep(1)
print("run0")

tasks = [asyncio.create_task(run0()),
asyncio.create_task(run0())]

asyncio.run(asyncio.wait(tasks))

会报错

1
2
RuntimeError: no running event loop
sys:1: RuntimeWarning: coroutine 'run0' was never awaited

因为执行

asyncio.create_task(run0())

的时候,会把 task 放到事件循环中,但是,此时事件循环还没有创建,变成下面这样就好了

1
2
3
4
5
6
7
8
9
10
11
import asyncio


async def run0():
await asyncio.sleep(1)
print("run0")


tasks = [run0(), run0()]

asyncio.run(asyncio.wait(tasks))

因为数组里放的是协程对象。

请我喝杯咖啡吧~