协程我们在上一篇文章里面提到了,现在我们正式介绍协程基础。
1.协程如何定义? 协程的本质还是一个函数,是一个异步函数,在普通的函数上加一个async
就行,所以协程的本质是一个异步函数;
2.协程如何运行? 协程直接按照普通函数使用是不会运行的:
async def paly_game(name:str):
print(name)
paly_game('kpl')
复制代码
运行结果:
RuntimeWarning: coroutine 'paly_game' was never awaited
paly_game('kpl')
复制代码
在现有的库提供了3种方式运行协程: (1)asyncio.run(异步函数/协程)
async def paly_game(name:str):
print(name)
asyncio.run(paly_game('kpl'))
复制代码
(2)await 异步函数/协程 利用await调用协程,我们可以看一个例子:
async def paly_game(name:str):
print(name)
async def play():
await paly_game('kpl')#调用paly_game
asyncio.run(play())
复制代码
需要注意的是,await是必须在函数内部使用,不然会报错:
async def paly_game(name:str):
print(name)
await paly_game()
复制代码
运行结果:
await paly_game()
^
SyntaxError: 'await' outside function
复制代码
(3)asyncio.create_task(异步函数/协程),然后运行task
async def paly_game(name:str):
print(name)
async def play():
task=asyncio.create_task(paly_game('kpl'))
await task
asyncio.run(play())
复制代码
await后面可以跟协程也可以跟协程的task,这两者有什么区别呢? 先看一下直接跟协程:
import asyncio
import time
async def paly_game(name:str,t:int):
await asyncio.sleep(t)
print(name)
async def play():
start=time.time()
await paly_game('kpl',2)
await paly_game('kpl',3)
print('spend total time is {}'.format(time.time()-start))
asyncio.run(play())
复制代码
运行结果:
kpl
kpl
spend total time is 5.016455888748169
复制代码
我们发现好像协程根本没有生效,还是3+2=5秒,实际上,只有使用task才会有类似于调度的协程发生:
import asyncio
import time
async def paly_game(name:str,t:int):
await asyncio.sleep(t)
print(name)
async def play():
start=time.time()
task1=asyncio.create_task(paly_game('kpl',2))
task2 = asyncio.create_task(paly_game('kpl', 3))
await task1
await task2
print('spend total time is {}'.format(time.time()-start))
asyncio.run(play())
复制代码
运行结果:
kpl
kpl
spend total time is 2.995018243789673
复制代码
现在我们的协程才会生效。