溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python的協(xié)程是什么

發(fā)布時間:2020-07-20 14:13:06 來源:億速云 閱讀:126 作者:清晨 欄目:編程語言

小編給大家分享一下Python的協(xié)程是什么,相信大部分人都還不怎么了解,因此分享這邊文章給大家學習,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去學習方法吧!

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

協(xié)程的概念很早就提出來了,但直到最近幾年才在某些語言(如Lua)中得到廣泛應用。

子程序,或者稱為函數,在所有語言中都是層級調用,比如A調用B,B在執(zhí)行過程中又調用了C,C執(zhí)行完畢返回,B執(zhí)行完畢返回,最后是A執(zhí)行完畢。

所以子程序調用是通過棧實現(xiàn)的,一個線程就是執(zhí)行一個子程序。

子程序調用總是一個入口,一次返回,調用順序是明確的。而協(xié)程的調用和子程序不同。

協(xié)程看上去也是子程序,但執(zhí)行過程中,在子程序內部可中斷,然后轉而執(zhí)行別的子程序,在適當的時候再返回來接著執(zhí)行。

注意,在一個子程序中中斷,去執(zhí)行其他子程序,不是函數調用,有點類似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中是沒有調用B的,所以協(xié)程的調用比函數調用理解起來要難一些。

看起來A、B的執(zhí)行有點像多線程,但協(xié)程的特點在于是一個線程執(zhí)行,那和多線程比,協(xié)程有何優(yōu)勢?

最大的優(yōu)勢就是協(xié)程極高的執(zhí)行效率。因為子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協(xié)程的性能優(yōu)勢就越明顯。

第二大優(yōu)勢就是不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比多線程高很多。

因為協(xié)程是一個線程執(zhí)行,那怎么利用多核CPU呢?最簡單的方法是多進程+協(xié)程,既充分利用多核,又充分發(fā)揮協(xié)程的高效率,可獲得極高的性能。

Python對協(xié)程的支持還非常有限,用在generator中的yield可以一定程度上實現(xiàn)協(xié)程。雖然支持不完全,但已經可以發(fā)揮相當大的威力了。

來看例子:

傳統(tǒng)的生產者-消費者模型是一個線程寫消息,一個線程取消息,通過鎖機制控制隊列和等待,但一不小心就可能死鎖。

如果改用協(xié)程,生產者生產消息后,直接通過yield跳轉到消費者開始執(zhí)行,待消費者執(zhí)行完畢后,切換回生產者繼續(xù)生產,效率極高:

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í)行結果:

Python的協(xié)程是什么

注意到consumer函數是一個generator(生成器),把一個consumer傳入produce后:

首先調用c.next()啟動生成器;

然后,一旦生產了東西,通過c.send(n)切換到consumer執(zhí)行;

consumer通過yield拿到消息,處理,又通過yield把結果傳回;

produce拿到consumer處理的結果,繼續(xù)生產下一條消息;

produce決定不生產了,通過c.close()關閉consumer,整個過程結束。

整個流程無鎖,由一個線程執(zhí)行,produce和consumer協(xié)作完成任務,所以稱為“協(xié)程”,而非線程的搶占式多任務。

最后套用Donald Knuth的一句話總結協(xié)程的特點:

“子程序就是協(xié)程的一種特例?!?/p>

以上是Python的協(xié)程是什么的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI