協程的理解(一)

通過廖雪峰的Python3學習教程網站學習與整理以下內容。

原文地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000

概念

協程,英文名:Coroutine

  • 協程是單線程執(zhí)行模式,因其執(zhí)行切換是由代碼自身控制,故有極高的執(zhí)行效率。與多線程相比,協程數量越多,協程的性能優(yōu)勢就越明顯。
  • 不需要多線程的鎖機制,不存在同時寫變量的沖突。在協程中控制共享資源不加鎖,只需要判斷狀態(tài)即可,故執(zhí)行效率比多線程高很多。
  • 因其是單線程模式,故采用 多進程+協程 的方式,充分利用CPU多核的計算處理能力,充分發(fā)揮其高效率。

協程執(zhí)行流程:

協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。因此協程能保留上一次調用時的狀態(tài)(即所有局部狀態(tài)的一個特定組合),每次過程重入時,就相當于進入上一次調用的狀態(tài),換種說法:進入上一次離開時所處邏輯流的位置。

實現方式

  • python 對 協程的支持是通過 generator(生成器) 實現的
  • 生成器Tips:
    • 可以使用 for 循環(huán)迭代
    • 可以使用 next() 迭代
    • 可以使用 send() 迭代
    • yield value 不但可以返回一個值,也可以接受調用者發(fā)出的參數(在下面的代碼示例中中能充分說明)

代碼示例及說明

def consumer():
    r = ''
    while True:
        # yield 返回 r, 并將 producer() 中 c.send(n)中的 n 賦值給 consumer中的 n
        n = yield r
        if not n:
            return
        print('[PRODUCER] Consuming %s...{}'.format(n))
        r = '200OK!'
        
def producer(m):
    m.send(None)
    n = 0
    while n < 5:
        n += 1
        print('[PRODUCER] Producing %s...{}'.format(n))
        # producer 通過 send() 將變量 n 作為參數傳給 consumer 中 yidle 接收的參數,
        # 并且將 yield 的返回值 賦給 res
        res = m.send(n)
        print('[PRODUCER] Consumer Return %s...{}'.format(res))
        
if __name__ == '__main__':
    c = consumer()
    producer(c)

執(zhí)行流程:

  1. 執(zhí)行腳本,首先執(zhí)行 if _name_ == '_main_'中的代碼塊
  2. 首先 produce() 函數執(zhí)行c.send(None) ,啟動生成器,consumer() 遇到 n = yield r ,此時 r = '', yield 返回 空 并停止執(zhí)行,進入等待
  3. produce()進入while循環(huán),q = 0 + 1 = 1,打印“[PRODUCER] Producing %s...1”
  4. res = c.send(q) 。 將 1 傳給consumer() ,此時 n = 1,if 判斷條件為False。并且打印 [PRODUCER] Consuming %s...1。r 被重新賦值為 '200OK!' 。
  5. 因為死循環(huán),程序再次執(zhí)行到 n = yield r ,程序停止運行,進入等待。
  6. producer() 函數中第19 行 res 接收 上述 yield 返回的 r 變量,即'200OK!' 。
  7. 打?。篬PRODUCER] Consumer Return %s...200OK!
  8. 接下來的從第 4 步開始循環(huán)執(zhí)行。

以上部分可以發(fā)現,consumer 內部一直被中斷,去執(zhí)行 producer 中的程序。而不是 consumer 完全執(zhí)行完。
這一點一定要吃透,否則無法理解 async 異步的流程。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容