异步编程 && 协程asyncio

协程

协程(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())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值