新聞中心
協(xié)程,又稱微線程,纖程。英文名Coroutine。

協(xié)程的概念很早就提出來了,但直到最近幾年才在某些語言(如Lua)中得到廣泛應用。
子程序,或者稱為函數(shù),在所有語言中都是層級調(diào)用,比如A調(diào)用B,B在執(zhí)行過程中又調(diào)用了C,C執(zhí)行完畢返回,B執(zhí)行完畢返回,最后是A執(zhí)行完畢。
所以子程序調(diào)用是通過棧實現(xiàn)的,一個線程就是執(zhí)行一個子程序。
子程序調(diào)用總是一個入口,一次返回,調(diào)用順序是明確的。而協(xié)程的調(diào)用和子程序不同。
協(xié)程看上去也是子程序,但執(zhí)行過程中,在子程序內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行別的子程序,在適當?shù)臅r候再返回來接著執(zhí)行。
注意,在一個子程序中中斷,去執(zhí)行其他子程序,不是函數(shù)調(diào)用,有點類似CPU的中斷。比如子程序A、B:
def A(): print '1' print '2' print '3' def B(): print 'x' print 'y' print 'z'
假設由協(xié)程執(zhí)行,在執(zhí)行A的過程中,可以隨時中斷,去執(zhí)行B,B也可能在執(zhí)行過程中中斷再去執(zhí)行A,結果可能是:
1 2 x y 3 z
但是在A中是沒有調(diào)用B的,所以協(xié)程的調(diào)用比函數(shù)調(diào)用理解起來要難一些。
看起來A、B的執(zhí)行有點像多線程,但協(xié)程的特點在于是一個線程執(zhí)行,那和多線程比,協(xié)程有何優(yōu)勢?
優(yōu)勢就是協(xié)程極高的執(zhí)行效率。因為子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數(shù)量越多,協(xié)程的性能優(yōu)勢就越明顯。
第二大優(yōu)勢就是不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比多線程高很多。
因為協(xié)程是一個線程執(zhí)行,那怎么利用多核CPU呢?最簡單的方法是多進程+協(xié)程,既充分利用多核,又充分發(fā)揮協(xié)程的高效率,可獲得極高的性能。
Python對協(xié)程的支持還非常有限,用在generator中的yield可以一定程度上實現(xiàn)協(xié)程。雖然支持不完全,但已經(jīng)可以發(fā)揮相當大的威力了。
來看例子:
傳統(tǒng)的生產(chǎn)者-消費者模型是一個線程寫消息,一個線程取消息,通過鎖機制控制隊列和等待,但一不小心就可能死鎖。
如果改用協(xié)程,生產(chǎn)者生產(chǎn)消息后,直接通過yield跳轉(zhuǎn)到消費者開始執(zhí)行,待消費者執(zhí)行完畢后,切換回生產(chǎn)者繼續(xù)生產(chǎn),效率極高:
import timedef consumer():
r = ''
while True:
n = yield r if not n: return
print('[CONSUMER] Consuming %s...' % n)
time.sleep(1)
r = '200 OK'def produce(c):
c.next()
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()if __name__=='__main__':
c = consumer()
produce(c)執(zhí)行結果:
注意到consumer函數(shù)是一個generator(生成器),把一個consumer傳入produce后:
首先調(diào)用c.next()啟動生成器;
然后,一旦生產(chǎn)了東西,通過c.send(n)切換到consumer執(zhí)行;
consumer通過yield拿到消息,處理,又通過yield把結果傳回;
produce拿到consumer處理的結果,繼續(xù)生產(chǎn)下一條消息;
produce決定不生產(chǎn)了,通過c.close()關閉consumer,整個過程結束。
整個流程無鎖,由一個線程執(zhí)行,produce和consumer協(xié)作完成任務,所以稱為“協(xié)程”,而非線程的搶占式多任務。
最后套用Donald Knuth的一句話總結協(xié)程的特點:
“子程序就是協(xié)程的一種特例。”
當前文章:創(chuàng)新互聯(lián)Python教程:一篇文章帶你讀懂Python的協(xié)程
路徑分享:http://m.5511xx.com/article/dhehdoc.html


咨詢
建站咨詢
