协程【Python】
基本概念
协程:,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,
多个任务按照一定顺序交替执行。
协程函数:采用async关键字修饰的函数;
协程对象: a = 协程函数,a就是coroutine对象;
Task: 由coroutine对象经过包装成为的任务;
Future:不常用,
协程定义
关键字: asyncio + def + funcName
import asyncio
async def func(num) -> None:
pass
运行协程函数
运行协程方式有多种,但主要步骤不变:创建循环;事件注册;运行协程
方式1
import asyncio
async def func(num) -> None:
print(num)
pass
#创建事件循环,运行协程函数;
loop = asyncio.get_event_loop()
loop.run_until_complete(a())
方式2
目前Python3.8这两种方式均可运行
import asyncio
async def func(num) -> None:
print(num)
pass
asyncio.run(func(2))
关键字await
await 关键字后面为可等待对象,可等待对象包括Coroutine、Task、Future;
主要功能:挂起程序和交出程序执行的控制权;如下程序执行到await被挂起,5s以后再执行。
import asyncio
import time
async def func() -> None:
print('开始执行%s'%time.strftime('%M:%S'))
await asyncio.sleep(5)
print('结束执行%s'%time.strftime('%M:%S'))
asyncio.run(func())
#执行结果
开始执行52:51
结束执行52:56
多协程任务切换
使用协程希望可以在IO等待时间内可以运行其他程序,将等待时间高效利用;
如下同步程序需要7s执行才能结束,异步只需要5s。大大提高了IO等待时间内的利用效率;
import asyncio
import time
async def func(name,sleeptime) -> None:
# print(time.strftime('%Y-%m-%d %H:%M:%S'))
print('{}开始执行{}'.format(name,time.strftime('%M:%S')))
await asyncio.sleep(sleeptime)
print('{}结束{}'.format(name,time.strftime('%M:%S')))
async def main():
task1 = asyncio.create_task(func('函数1',2))
task2 = asyncio.create_task(func('函数2',5))
task = [task1,task2]
await asyncio.wait(task)
if __name__ == '__main__':
asyncio.run(main())
#执行结果
函数1开始执行07:33
函数2开始执行07:33
函数1结束07:35
函数2结束07:38
asyncio.wait()
asyncio.wait()第一个入参可以是一个Coroutine对象或者Task对象列表,返回值一个为done和pedding。done为完成协程的集合,pedding为未完成失败的协程集合。
wait(fs: Iterable[_FutureT[_T]], *, loop: Optional[AbstractEventLoop] = ..., timeout: Optional[float] = ...,
return_when: str = ...) -> Future[Tuple[Set[Future[_T]], Set[Future[_T]]]]: ...
done,pedding = await asyncio.wait(task)
print(done)
print(pedding)
#运行结果
{<Task finished name='函数2' coro=<func() done, defined at ** result=None>,
<Task finished name='函数1' coro=<func() done, defined at ** result=None>}
set()
返回的done为运行结束的两个协程;没有失败的因此pedding为空集合。