本文主要介紹一下協程的基本概念、對比多線程的優勢,以及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系列是一樣的
py2.png
- 從結果上來看,多線程于協程的效果一樣,都是達到了IO阻塞時切換的功能。協程切換的是上下文(函數),多線程切換的是線程。
IV、Python3.x協程
Python3.x系列的協程還是有很多不同的地方,以後再吧這個坑補上,這主要介紹下主要的
asyncio
- asyncio是Python3.4引進的标準庫,直接内置了對IO的支援,asyncio的一部操作,需要在coroutine中通過yield from完成
- 它的效果是和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
V、總結
以上是Python協程的基礎用法,以及比較成熟的類庫,後面慢慢補上版本差異以及對應不同方法的不同作用