异步前提条件
- python 3.5以上
- 若使用第三方库,库必须支持异步
async和await
关于async和await:
- async和await必须成对出现
- async表示该函数可以异步执行
- await表示代码执行到此处,协程可以切出执行其他任务
- await如果得到结果,协程需要切回此处继续执行后面的代码
单个任务异步
python 3.5提供async
和await
,来实现异步调用
有的库提供异步的函数修饰器,可以用库接口,当然最好是用原生的async
和await
import asyncio
async def hello(num):
print('Hello {}'.format(num))
await asyncio.sleep(1)
return 'World {}'.format(num)
if __name__ == '__main__':
asyncio.run(hello(1))
多个任务异步
错误写法
单个任务async其实没有什么意义,多个任务同时跑动,异步才会有效
但是多个任务异步不能用for循环简单的把多个任务串在一起,以下是错误写法,该写法其实会导致,10个异步任务还是顺序执行的,并且会耗时10S
import asyncio
async def run_task():
for i in range(10):
await hello(i)
async def hello(num):
print('Hello {}'.format(num))
await asyncio.sleep(1)
return 'World {}'.format(num)
if __name__ == '__main__':
asyncio.run(run_task())
# 以下这种方式也是错的
# for i in range(10):
# asyncio.run(hello(i))
正确写法
使用async_wait或者async_gather批量执行任务,以下程序耗时约为1S,10个任务1S执行完
import asyncio
async def run_task():
for i in range(10):
print(await hello(i))
async def hello(num):
print('Hello {}'.format(num))
await asyncio.sleep(1)
return 'World {}'.format(num)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
tasks = []
for i in range(10):
task = asyncio.ensure_future(hello(i))
tasks.append(task)
# 如果不关心结果,可以用wait
result = loop.run_until_complete(asyncio.wait(tasks))
# 关心结果,则使用gather
# result = loop.run_until_complete(asyncio.gather(*tasks))
# print(result)
loop.close()