抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

异步编程

事件循环

死循环,检测代码并执行某些代码

1
2
3
4
5
6
7
8
9
10
11
任务列表 = [任务1,任务2,任务3...]

while True:
  可执行的任务列表,已完成的任务列表 = 去任务列表中检查所有的任务,将"可执行"和"已完成"的任务返回
  for 就绪任务 in 可执行的任务列表:
     执行已就绪的任务
  for 已完成的任务 in 已完成的任务列表:
     再任务列表中移除 已完成任务

  如果任务列表中的任务都已完成,则终止循环

快速上手

协程函数,定义函数为async def 函数名
协程对象,执行 协程函数() 得到的协程对象

1
2
3
4
5
6
import asyncio

async def func():
pass

result = func()

注意:执行协程函数创建协程对象,函数内部代码不会执行
如果想要运行协程函数内部代码,必须要将协程对象交给事件循环来处理

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

async def func():
print("test")

result = func()

loop = asyncio.get_event_loop()
loop.run_until_complete(result)
# asyncio.run(result )

await关键字

await + 可等待对象(协程对象、Future、Task对象)-> IO等待
一个协程函数中可以存在多个await
示例:

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

async def others():
print("start")
await asyncio.sleep(2)
print("end")
  return "返回值"

async def func():
  print("执行协程函数内部代码")
response = await others()
  print("IO请求结束, 结果为:" + response)

asyncio.run(func())

输出结果

1
2
3
4
5
执行协程函数内部代码
start
----------停顿
end
IO请求结束,结果为: 返回值

task对象

Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Tak对象,这样可以让协程加入事件循环中等待被调度执行。除了使用asyncio.create_task()函数以外,还可以用低层级的loop.create_task()或ensure_future()函数,不建议手动实例化Task对象。

示例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import asyncio

async def func():
print(1)
await asyncio.sleep(2)
print(2)
  return "返回值"

async def main():
  print("main 开始")

  # 创建Task对象,将当前执行func函数任务添加到事件循环中

  task1 = asyncio.create_task(func())
# 创建Task对象,将当前执行func函数任务添加到事件循环中
task2 = asyncio.create_task(func())

  print("main 结束")

  # 当执行某协程遇到IO操作时,会自动化切换执行其他任务
  # 此处的await是等待相应的协程全都执行完毕并获取结果
  ret1 = await task1
ret2 = await task2

asyncio.run(main())

输出结果

1
2
3
4
5
6
7
8
main 开始
main 结束
1
1
---------sleep(2秒)
2
2
返回值 返回值

示例2

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

async def func():
print(1)
await asyncio.sleep(2)
print(2)
  return "返回值"


async def main():
  print("main 开始")

task_list = [
asyncio.create_task(func(), name="task1")
asyncio.create_task(func(), name="task2")
]

  print("main 结束")
  done, pending = await asyncio.wait(task_list)
print(done)

asyncio.run(main())

输出结果

1
2
3
4
5
6
7
8
main 开始
main 结束
1
1
--------sleep(2秒)
2
2
{<Task finished name='task1' coro=<func() done, defined at C:/Users/v_zquanwang/Desktop/python-asycion/task_test.py:25> result='返回值'>, <Task finished name='task2' coro=<func() done, defined at C:/Users/v_zquanwang/Desktop/python-asycion/task_test.py:25> result='返回值'>}

async Future对象

Task对象继承Future,Task对象内部await结果的处理基于Future对象来的

concurrent.futures.Future对象

使用线程池、进程池实现异步操作时用到的对象

异步迭代器

异步上下文管理器

此种对象通过定义__aenter__()__aexit__()方法来对async_with语句中的环境进行控制

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

class AsyncContextManager:
def __init__(self):
self.conn = conn
async def do_something(self):
     # 异步操作数据库
return 666
  async def __aenter__(self):
     # 异步连接数据库
self.conn = await asyncio.sleep(2)
return self
async def __aexit__(self, exc_type, exc, tb):
await asyncio.sleep(2)

async def func():
async with AsyncContextManager as f:
result = await f.do_something()
print(result)


asyncio.run(func())

评论