文章目录
- 协程
- greenlet
- yield
- asyncio
- async / await
- 协程意义
- 异步编程
协程
协程(Coroutine)不是计算机提供,程序员人为创造
协程也可以称为微线程, 是一种用户态的上下文切换技术。就是通过一个线程实现代码块相互切换执行。
实现协程方法:
- greenlet
- yield
- asyncio 装饰器
- async/await 关键字
greenlet
pip install greenlet
from greenlet import greenletdef func1():print(1) gr2.switch() print(2) gr2.switch() def func2():print(3) gr1.switch() print(4) gr1 = greenlet(func1)
gr2 = greenlet(func2)gr1.switch()
yield
def func1():yield 1yield from func2()yield 2def func2():yield 3yield 4for item in func1():print(item)
asyncio
python 3.4 之后支持
import asyncio@asyncio.coroutine
def func1():print(1)yield from asyncio.sleep(2)print(2)@asyncio.coroutine
def func2():print(3)yield from asyncio.sleep(2)print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
遇到 IO 阻塞自动切换
async / await
python 3.5 之后支持
import asyncioasync def func1():print(1)await asyncio.sleep(2)print(2)async def func2():print(3)await asyncio.sleep(2)print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
协程意义
一个线程中遇到 IO 等待时,线程不会傻等,利用空闲时间完成其他任务
异步编程
事件循环
事件循环的作用是管理所有的事件,在整个程序运行过程中不断循环执行,追踪事件发生的顺序将它们放到队列中,当主线程空闲的时候,调用相应的事件处理者来处理事件
快速上手
- 协程函数:async def 函数名
- 协程对象:执行 协程函数() 得到协程对象
async def func():pass
result = func()
async def func():print('test')res = func()loop = asyncio.get_event_loop()
loop.run_until_complete(res)
asyncio.run(res)
await
await + 可等待的对象 (协程对象, Future, Task对象) IO等待
async def test():print('test')res = await asyncio.sleep(2)
Task对象
Tasks 用于并发调度协程,通过 asyncio.create_task(协程对象)
的方式创建 Task 对象,这样可以让协程加入事件循环中等到被调度执行
async def test():print('test satart...')await asyncio.sleep(2)async def main():print('start...')task1 = asyncio.create_task(test())task2 = asyncio.create_task(test())await task1await task2asyncio.run(main())
async def test():print('test satart...')await asyncio.sleep(1)return '1'async def main():tasks = [asyncio.create_task(test()),asyncio.create_task(test()),]await asyncio.wait(tasks)asyncio.run(main())