协程
协程(Coroutine)不是计算机提供,程序员人为创造
协程也可以称为微线程, 是一种用户态的上下文切换技术。就是通过一个线程实现代码块相互切换执行。
实现协程方法:
- greenlet
 - yield
 - asyncio 装饰器
 - async/await 关键字
 
greenlet
pip install greenlet
  from greenlet import greenlet
def func1():
    print(1)             # 2. 输出 1
    gr2.switch()         # 3. 切换到 func2 函数
    print(2)             # 6. 输出 2
    gr2.switch()         # 7. 切换到 func2 函数,从上一次执行位置向后执行
def func2():
    print(3)             # 4. 输出 3
    gr1.switch()         # 5. 切换到 func1 函数,从上一次执行位置向后执行
    print(4)             # 8. 输出 4
gr1 = greenlet(func1)
gr2 = greenlet(func2)
gr1.switch()              # 1. 执行 func1 函数
  yield
def func1():
    yield 1
    yield from func2()
    yield 2
def func2():
    yield 3
    yield 4
for 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 asyncio
async 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)
# py3.7+
asyncio.run(res)
  await
await + 可等待的对象 (协程对象, Future, Task对象) IO等待
async def test():
    print('test')
    res = await asyncio.sleep(2)
  Task对象
Tasks 用于并发调度协程,通过 asyncio.create_task(协程对象) 的方式创建 Task 对象,这样可以让协程加入事件循环中等到被调度执行
# Example 1
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 task1
    await task2
asyncio.run(main())
# start...
# test satart...
# test satart...
# sleep 2
  # Example 2
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())

京公网安备 11010502036488号