天天看點

Python 實作協程

  協程,又稱微線程,纖程。英文名coroutine。一句話說明什麼是線程:協程是一種使用者态的輕量級線程。(其實并沒有說明白~)

我覺得單說協程,比較抽象,如果對線程有一定了解的話,應該就比較好了解了。

那麼這麼來了解協程比較容易:

  線程是系統級别的,它們是由作業系統排程;協程是程式級别的,由程式員根據需要自己排程。我們把一個線程中的一個個函數叫做子程式,那麼子程式在執行過程中可以中斷去執行别的子程式;别的子程式也可以中斷回來繼續執行之前的子程式,這就是協程。也就是說同一線程下的一段代碼<1>執行着執行着就可以中斷,然後跳去執行另一段代碼,當再次回來執行代碼塊<1>的時候,接着從之前中斷的地方開始執行。

比較專業的了解是:

  協程擁有自己的寄存器上下文和棧。協程排程切換時,将寄存器上下文和棧儲存到其他地方,在切回來的時候,恢複先前儲存的寄存器上下文和棧。是以:協程能保留上一次調用時的狀态(即所有局部狀态的一個特定組合),每次過程重入時,就相當于進入上一次調用的狀态,換種說法:進入上一次離開時所處邏輯流的位置。

子程式(函數)在執行過程中可以中斷去執行别的子程式;别的子程式也可以中斷回來繼續執行之前的子程式”,那麼很容易想到python的yield,顯然yield是可以實作這種切換的。

使用yield實作協程操作例子:

輸出:

python的 greenlet就相當于手動切換,去執行别的子程式,在“别的子程式”中又主動切換回來。。。

輸出

gevent 是一個第三方庫,可以輕松通過gevent實作協程程,在gevent中用到的主要模式是greenlet, 它是以c擴充子產品形式接入python的輕量級協程。 greenlet全部運作在主程式作業系統程序的内部,但它們被協作式地排程。

gevent會主動識别程式内部的io操作,當子程式遇到io後,切換到别的子程式。如果所有的子程式都進入io,則阻塞。