python异步IO和协程

本文深入探讨Python的异步IO和协程概念,包括异步IO的工作原理、协程的调用方式和在Python中的实现。通过示例解释了如何在Python中使用生成器实现协程,以及Python3.5后的async和await语法。同时,文章还介绍了Event Loop在异步编程中的重要性,展示了如何在事件循环中调度和执行协程。
摘要由CSDN通过智能技术生成

本文对python协程做一些总结,来自平时的学习和一些博客资料


1. 异步IO

关于异步IO的讲解,网上资料太多了,我以前的文章也提到过,此处只做一些简单介绍:

  • 异步IO采用消息循环的模式,重复“读取消息—处理消息”的过程
  • 消息模型解决等待IO操作的问题:
    • 程序发出IO请求,直接结束本轮消息处理,进入下一轮消息的处理
    • 当IO操作完成守,将收到一条IO完成的消息,处理该消息时获取IO操作的结果
    • 在IO操作的这段时间里,异步模型可以循环处理其他操作,而且没有线程切换的消耗,同时处理多个IO请求,适用于大多数IO密集型的应用程序。

python 的异步协程 (async coroutine) ,在提交 HTTP 请求后,就没必要等待请求完成再进一步操作,而是可以一边等着请求完成,一边做着其他工作。这可能在逻辑上需要多些思考来保证程序正确运行,但是好处是可以利用更少的资源做更多的事。

2. 协程概念

协程是python异步IO中常用的一个概率,英文为coroutine。协程不同于进程和线程,在某种程度上,它的概念更接近于函数调用的概念。

2.1 函数调用:

我们知道,程序执行中,函数调用是通过函数栈实现,因为栈FILO的特点,通常函数调用过程都是:A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。子程序(函数)调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

2.1 协程调用:

协程和函数最相似的地方就是协程本身的定义就更函数很像,而其调用也很相像。

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

协程针对的是一个线程中的函数调用之间,所以没有线程切换,是在一个线程中轮流执行和终端多个函数而已,所以效率较高,而且不需要锁机制(只有一个线程执行)

需要注意的是,子程序内部中断的不是函数调用,而是被调用函数中断(一般来说可能是一条执行命令需要很长时间等待结果返回,比如常见的IO操作),转而去执行另一个函数(不是调用另一个函数),类似两个函数轮流执行,没有发生函数调用。

上述的执行流程看上去很像多线程有木有!!!实际上,一些协程的执行结果也很像多线程的执行结果,因为本质就是不同代码段轮流执行,进而提高效率。协程得到运用主要在于其效率更高:

协程的执行效率较高,因为不是线程切换,而是程序控制,没有开销。因为是一个线程中有多个协程,所以不需要锁机制。

此外,多线程编程中锁机制的开销在协程中也不存在,因为协程不需要锁机制:

因为协程执行是在一个线程中,不存在同时写变量冲突,所以共享资源不需要加锁,只需要判断状态就好,进一步提升效率。

3. python中的协程操作

python中协程的支持是通过生成器(generator)实现的。

熟悉generator的知道:函数定义时,将函数的结果通过yield返回,则定义了一个生成器,而在生成器中,我们不但可以通过for循环来迭代,还可以不断调用next()函数获取由yield语句返回的下一个值。

而对于协程来说,yield不但可以返回一个值,它还能接收函数调用者发出的参数。(这句话很重要)

下面运用网上教程讲解的一个例子(我觉的很清晰)来说明协程操作:

传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高:

代码如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值