天天看點

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協程的基礎用法,以及比較成熟的類庫,後面慢慢補上版本差異以及對應不同方法的不同作用