Python-异步IO编程

本文介绍了一种高级的并发编程模式,异步IO(asyncio)和协程,是用户态高效率并发编程的一种常用解决方案,往往是构建 IO 密集型和高层级结构化网络代码的最佳选择。asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任 务队列等等。本文以 Python3.7 为准。

异步 IO
  • 老生常谈:线程、进程
    • 多线程善于处理 I/O 密集型任务。
    • 多进程擅长处理计算密集型(CPU-bound)任务:强密集循环和数学计算都属于此类。
    • 并发是并行的一种特殊类型(或者说子类),多线程是并发的表现形式,多进程是并行的表现形式。
    • Python 通过它的包 multiprocessing,threading 和 concurrent.futures 已经对这两种形式都提供了长期的支持。
  • 操作系统中的 IO 访问方式
    • 阻塞 I/O(blocking IO),访问数据时线程会阻塞等待结果
    • 非阻塞 I/O(nonblocking IO),访问数据时线程会轮训结果
    • I/O 多路复用( IO multiplexing),访问数据时线程能批量(select/poll/epoll)阻塞等待结果
    • 信号驱动 I/O( signal driven IO),访问数据时线程批量阻塞等待系统信号通知
    • 异步 I/O(asynchronous IO),访问数据时不需要等待,只需要处理系统信号
  • 异步 IO 的特性:
    • 异步 IO 是一种单进程、单线程的设计:它使用协同多任务处理机制,是以协程为核心的一种编程模型。
    • 异步 IO 采用消息循环的模式,在消息循环中,主线程不断地重复“读取消息-处理消息”这一过程
    • 在异步 IO 模型下,一个线程就可以同时处理多个 IO 请求,并且没有切换线程的操作,因此,对于大多数 IO 密集型的应用程序,使用异步 IO 将大大提升系统的多任务处理能力。
  • 异步 IO 的消息模型:
    • 当遇到 IO 操作时,代码只负责发出 IO 请求,不等待 IO 结果,然后直接结束本轮消息处理,进入下一轮消息处理过程。
    • 当 IO 操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取 IO 操作结果。
    • 在“发出IO请求”到收到“IO完成”的这段时间里,同步 IO 模型下,主线程只能挂起,但异步 IO 模型下,主线程并没有休息,而是在消息循环中继续处理其他消息。
loop = get_event_loop()      # 实例消息队列
while True:
    event = loop.get_event() # 从队列中读取消息
    process_event(event)    
协程(Coroutine)
  • 协程拥有自己的寄存器上下文和栈,调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈;
  • 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置;
  • 协程无需线程上下文切换的开销;
  • 协程无需原子操作锁定及同步的开销;
  • 协程方便切换控制流,简化编程模型;
  • 协程的本质是个单线程,它不能同时将 CPU 的多个核用上;
  • PS: 协程的概念和使用方式,与单片机的嵌入式操作系统类似。
Python 的协程 asyncio
  • Python 3.1 版本中,协程操作只是简单的生成器调用,常见的我们还需要在生成器或者说协程之间相互调用,用到 yield from;
  • 在 python3.5 版本中,创建一个协程仅仅只需使用async关键字,而 Python3.4 使用 @asyncio.coroutine 装饰器;
  • 协程,使用async原语可以定义一个协程
import asyncio

async def main():
    print('Hello ...')
    await asyncio.sleep(1)
    print('... World!')

asyncio.run(main())

<未完待续>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值