python3之攜程yield及greenlet

2021-10-04 22:22:24 字數 1767 閱讀 9790

協程,又稱微執行緒,纖程。英文名coroutine。

執行緒是系統級別的它們由作業系統排程,而協程則是程式級別的由程式根據需要自己排程。在乙個執行緒中會有很多函式,我們把這些函式稱為子程式,在子程式執行過程中可以中斷去執行別的子程式,而別的子程式也可以中斷回來繼續執行之前的子程式,這個過程就稱為協程。也就是說在同一執行緒內一段**在執行過程中會中斷然後跳轉執行別的**,接著在之前中斷的地方繼續開始執行,類似與yield操作。

協程擁有自己的暫存器上下文和棧。協程排程切換時,將暫存器上下文和棧儲存到其他地方,在切回來的時候,恢復先前儲存的暫存器上下文和棧。因此:協程能保留上一次呼叫時的狀態(即所有區域性狀態的乙個特定組合),每次過程重入時,就相當於進入上一次呼叫的狀態,換種說法:進入上一次離開時所處邏輯流的位置。

協程的優點:

(1)無需執行緒上下文切換的開銷,協程避免了無意義的排程,由此可以提高效能(但也因此,程式設計師必須自己承擔排程的責任,同時,協程也失去了標準執行緒使用多cpu的能力)

(2)無需原子操作鎖定及同步的開銷

(3)方便切換控制流,簡化程式設計模型

(4)高併發+高擴充套件性+低成本:乙個cpu支援上萬的協程都不是問題。所以很適合用於高併發處理。

協程的缺點:

(1)無法利用多核資源:協程的本質是個單執行緒,它不能同時將 單個cpu 的多個核用上,協程需要和程序配合才能執行在多cpu上.當然我們日常所編寫的絕大部分應用都沒有這個必要,除非是cpu密集型應用。

(2)進行阻塞(blocking)操作(如io時)會阻塞掉整個程式

import time

defcustomer

(name)

:print

("\033[31;1m[customer_%s]\033[0m need baozi"

%name)

while

true

: new_baozi =

yield

print

("[%s] is eating baozi %s"

%(name, new_baozi)

)def

producter()

: con.__next__(

)for i in

range(1

,6):

print

("\033[32;1m[producer]\033[0m is ****** baozi %s"

% i)

# send後yield才能放行

con.send(i)

time.sleep(1)

if __name__ ==

"__main__"

:# 建立物件

con = customer(

"c1"

) p = producter(

)

greenlet實現攜程案例(greenlet需要自己匯入包)

from greenlet import greenlet

deffunc1()

:print(1

) g2.switch(

)print(3

) g2.switch(

)def

func2()

:print(2

) g1.switch(

)print(4

)g1 = greenlet(func1)

g2 = greenlet(func2)

g1.switch(

)

python 3 協程函式

1 把函式的執行結果封裝好 iter 和 next 即得到乙個迭代器 2 與return功能類似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值 3 函式暫停與再繼續的狀態是由yield儲存的 def func count print start while tru...

python3協程學習筆記

在此之前,協程對我來說是乙個比較陌生的概念,學習之後,發現其應用場景還是有不少,大師之言 協程能自然地表述很多演算法,例如 遊戲 非同步i o,以及其他事件驅動型邊吃形式活協作式多工。舉例來說,asyncio tornado twisted simpy庫都是基於協程特性在單個執行緒中管理多個併發活動...

Python3 生成器與yield

斐波那契數列指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 importtime def fib times a 0 b 1 n 1 while n times print b a,b b,a b n 1 fib 7 生成器寫法 deffib times a 0 b 1 n 1 whi...