天天看点

python 协程

本文主要介绍一下协程的基本概念、对比多线程的优势,以及Python2.x系列和Python3.x系列的大体差别

I、概念

协程(coroutine),又称为微线程,纤程。协程的作用:在执行A函数的时候,可以随时中断,去执行B函数,然后中断继续执行A函数(可以自动切换),单着一过程并不是函数调用(没有调用语句),过程很像多线程,然而协程只有一个线程在执行

II、优势

协程可以很完美的处理IO密集型的问题,但是处理cpu密集型并不是他的长处。要充分发挥CPU的性能,可以结合多进程+多线程的方式。 ​​IO密集型和CPU密集型​​

  • 执行效率高,因为子程序切换函数,而不是线程,没有线程切换的开销,由程序自身控制切换。于多线程相比,线程数量越多,切换开销越大,协程的优势越明显
  • 不需要锁的机制,只有一个线程,也不存在同时写变量冲突,在控制共享资源时也不需要加锁。

III、Python2.x协程

类库:

  • yield
  • gevent

Gevent 是第三方库,通过greenlet实现,其基本思想:

  • 当一个greenlet遇到IO操作时,就自动切换到其他的greelet,等到IO操作完成,再适当的时候切换回来继续执行。gevent自动切换协程,保证总有greelet在运行,而不是等待IO

Python3.x系列的geven用法和python2.x系列是一样的

python 协程
python 协程

py2.png

  • 从结果上来看,多线程于协程的效果一样,都是达到了IO阻塞时切换的功能。协程切换的是上下文(函数),多线程切换的是线程。

IV、Python3.x协程

Python3.x系列的协程还是有很多不同的地方,以后再吧这个坑补上,这主要介绍下主要的

asyncio

  • asyncio是Python3.4引进的标准库,直接内置了对IO的支持,asyncio的一部操作,需要在coroutine中通过yield from完成
python 协程
python 协程
python 协程
  • 它的效果是和Gevent一样的,遇到IO操作的时候,自动切换上下文。
  • 不同的是,它在tasks的操作:
  • task先把这个5个参数不同的函数全部加载进来,在执行任务,在这个过程中,任务执行是无序的
  • @asyncio.coroutine把一个generator标记为coroutine类型,然后把这个coroutine扔到eventloop中执行
  • yield from 语法让我们方便的调用另一个generator。由于asyncio.sleep()也是一个coroutine,线程不会等待,直接中断执行下一个消息循环。当asyncio.sleep()返回时,线程可以从yield from拿到返回值(此处是None),然后接着执行下一行语句

async/await

  • 为了更好的表示异步IO,Python3.5开始引入了新的语法,async和await,让coroutine语法更简洁,它们是针对coroutine的新语法,只需要把@asyncio.coroutine替换为async、yield from替换为await
    python 协程
python 协程

V、总结

以上是Python协程的基础用法,以及比较成熟的类库,后面慢慢补上版本差异以及对应不同方法的不同作用