Python 高階 之 協程

2022-03-11 10:51:51 字數 4482 閱讀 7990

協程的概念級描述(與執行緒對比):**知乎 鏈結

執行緒有兩個必須要處理的問題:一是碰著阻塞式i\o會導致整個程序被掛起;

二是由於缺乏時鐘阻塞,程序需要自己擁有排程執行緒的能力。

如果一種實現使得每個執行緒需要自己通過呼叫某個方法,主動交出控制權。那麼我們就稱這種執行緒是協作式的,即是協程。

在python中關於協程的實現方式有三種:

最初的生成器變形yield/send

引入@asyncio.coroutine和yield from

在python3.5版本中引入async/await關鍵字

以下**均在centos 7 python3.6除錯通過!

簡單的yield使用描述:

def

fun():

index =0

while

true:

yield

index

index += 1

if index > 3:

break

for i in

fun():

print (i)

輸出:0 1 2 3

在此例中yield做的事是:

1:將函式fun的返回值設定為乙個生成器

2:每次執行至yield index 時會將index的值作為生成器的下乙個元素返回值for迴圈並且被賦值給變數i,用print輸出出來

簡單的yield/send使用描述:

def

fun():

index =0

while

true:

value = yield

index

print ("

value=

" +str(value))

print ("

index=

" +str(index))

index += 1

if index > 3:

break

funobj =fun()

print

(type(funobj))

print ("

next=

" +str(next(funobj)))

for i in

funobj:

print ("

i=" +str(i))

try:

funobj.send(i+100)

except

stopiteration:

print("

it's stop

")輸出:

next=0

value=none

index=0

i=1value=101

index=1

value=none

index=2

i=3value=103

index=3

it's stop

不是很精通,因此**有點亂。

解釋:首先宣告了fun函式,並將fun賦給了對面funobj,funobj是乙個迭代器。next(funobj)初始化並啟動迭代器,程式開始執行fun函式至value = yield index(第一次)結束,yield返回了第乙個index值0 next=0

for i in funobj:啟動迭代器,因此此時send還未傳值,因此value和next都是空,value=none index=0 程式執行fun函式至value = yield index(第二次)結束,yield返回了第二個index值1i=1

注意之後send傳送了值101,for再次啟動迭代器,從yield啟動時捕獲到此值101,value=101 index=101。此後類似。

迭代器結束時會捕獲到 stopiteration異常,將此捕獲並輸出出來 it's stop

簡單的yield/send使用描述:

yeild from語法就是將生成器函式中包括yield語句的部分邏輯封裝到乙個子生成器函式中。然後在子生成器函式外面可以做一些其他的業務邏輯。整個生成器函式(包括子生成器函式)對外就是乙個生成器函式。

def

fun():

index =0

while

true:

value = yield

index

print ("

value=

" +str(value))

print ("

index=

" +str(index))

index += 1

if index > 3:

break

deffun2():

print ("

before ")

yield

from

fun()

print ("

end ")

funobj =fun2()

print

(type(funobj))

print ("

next=

" +str(next(funobj)))

for i in

funobj:

print ("

i=" +str(i))

try:

funobj.send(i+100)

except

stopiteration:

print("

it's stop

")

輸出:

'generator

'>before

next=0

value=none

index=0

i=1value=101index=1value=none

index=2i=3value=103index=3end it'

s stop

簡單的asyncio.coroutine使用描述:(參考自廖雪峰的官方**)

@asyncio.coroutine通過裝飾器呼叫,作用是把乙個generator標記為coroutine型別:

import

asyncio

@asyncio.coroutine

defhello():

print("

hello world!")

#非同步呼叫asyncio.sleep(1):

r = yield

from asyncio.sleep(1)

print("

hello again!")

#獲取eventloop:

loop =asyncio.get_event_loop()

#執行coroutine

loop.run_until_complete(hello())

loop.close()

輸出:

hello world!

hello again!

簡單的asyncawait使用描述:

asyncawait是針對coroutine的新語法,要使用新的語法,只需要做兩步簡單的替換:

@asyncio.coroutine替換為async

yield from替換為await

示例**:

import

asyncio

async

defhello():

print("

hello world!")

r = await asyncio.sleep(1)

print("

hello again!")

#獲取eventloop:

loop =asyncio.get_event_loop()

#執行coroutine

loop.run_until_complete(hello())

loop.close()

需要注意的是asyncawait只能用在python 3.5以及後續版本,如果使用3.4版本,則仍需使用asyncio.coroutine和yield from方案。

示例可能出現的報錯如下:

[root@jans test]#

python3.6 c.py

hello world!

hello again!

[root@jans test]

#python3.4 c.py

file "

c.py

", line 3async

defhello():

^syntaxerror: invalid syntax

Python高階之協程詳解

目錄 協程 co routine,又稱微執行緒 是一種多方協同的工作方式。當前執行者在某個時刻主動讓出 yield 控制流,並記住自身當前的狀態,以便在控制流返回時能從上次讓出的位置恢復 resume 執行。簡而言之,協程的核心思想就在於執行者對控制流的 主動讓出 和 恢復 相對於,執行緒此類的 搶...

python高階 協程

def demo1 for i in range 3 print 正在執行demo1 format i yield defdemo2 for i in range 3 print 正在執行demo2 format i yield g1 demo1 g2 demo2 print g1 while tr...

Python之協程技術

1.定義 纖程,微執行緒。是允許在不同入口點不同位置暫停或開始的電腦程式,簡單來說,協程就是可以暫停執行的函式。2.協程原理 記錄乙個函式的上下文,協程排程切換時會將記錄的上下文儲存,在切換回來時進行調取,恢復原有的執行內容,以便從上一次執行位置繼續執行。協程本質上就是乙個執行緒,以前多執行緒任務的...