在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 協(xié)程
基礎(chǔ)
itertools
HTTP 服務(wù)
hashlib
閉包
文件和目錄
單元測(cè)試
使用 @property
標(biāo)準(zhǔn)模塊
陌生的 metaclass
Base64
進(jìn)程、線程和協(xié)程
讀寫二進(jìn)制文件
匿名函數(shù)
輸入和輸出
Click
元組
字符編碼
partial 函數(shù)
參考資料
collections
協(xié)程
類和實(shí)例
Python 之旅
定制類和魔法方法
常用數(shù)據(jù)類型
繼承和多態(tài)
ThreadLocal
HTTP 協(xié)議簡(jiǎn)介
Requests 庫(kù)的使用
讀寫文本文件
列表
os 模塊
迭代器 (Iterator)
正則表達(dá)式
集合
上下文管理器
異常處理
你不知道的 super
定義函數(shù)
datetime
資源推薦
字典
slots 魔法
hmac
第三方模塊
進(jìn)程
類方法和靜態(tài)方法
函數(shù)參數(shù)
高階函數(shù)
函數(shù)
re 模塊
高級(jí)特性
線程
argparse
生成器
結(jié)束語(yǔ)
字符串
map/reduce/filter
函數(shù)式編程
Celery
裝飾器

協(xié)程

與子程序(或者說函數(shù))一樣,協(xié)程(coroutine)也是一種程序組件。Donald Knuth 曾說,子程序是協(xié)程的特例。

一個(gè)子程序就是一次函數(shù)調(diào)用,它只有一個(gè)入口,一次返回,調(diào)用順序是明確的。但協(xié)程的調(diào)用和子程序則大不一樣,協(xié)程允許有多個(gè)入口對(duì)程序進(jìn)行中斷、繼續(xù)執(zhí)行等操作。

Python2 可以通過 yield 來實(shí)現(xiàn)基本的協(xié)程,但不夠強(qiáng)大,第三方庫(kù) gevent 對(duì)協(xié)程提供了強(qiáng)大的支持。另外,Python3.5 提供了 async/await 語(yǔ)法來實(shí)現(xiàn)對(duì)協(xié)程的支持。本文只討論通過 yield 來實(shí)現(xiàn)協(xié)程。

對(duì)于經(jīng)典的生產(chǎn)者-消費(fèi)者模型,如果用多線程來實(shí)現(xiàn),我們就需要一個(gè)線程寫消息,一個(gè)線程讀消息,而且需要鎖機(jī)制來避免對(duì)共享資源的訪問沖突。

相比多線程,協(xié)程的一大特點(diǎn)就是它在一個(gè)線程內(nèi)執(zhí)行,既避免了多線程之間切換帶來的開銷,也避免了對(duì)共享資源的訪問沖突。

下面,讓我們看看怎么用 yield 來實(shí)現(xiàn)簡(jiǎn)單的生產(chǎn)者-消費(fèi)者模型。

import time

def consumer():
    message = ''
    while True:
        n = yield message     # yield 使函數(shù)中斷
        if not n:
            return
        print '[CONSUMER] Consuming %s...' % n
        time.sleep(2)
        message = '200 OK'

def produce(c):
    c.next()           # 啟動(dòng)生成器
    n = 0
    while n < 5:
        n = n + 1
        print '[PRODUCER] Producing %s...' % n
        r = c.send(n)  # 通過 send 切換到 consumer 執(zhí)行
        print '[PRODUCER] Consumer return: %s' % r
    c.close()

if __name__ == '__main__':
    c = consumer()
    produce(c)

在上面的代碼中,消費(fèi)者 consumer 是一個(gè)生成器函數(shù),我們把它作為參數(shù)傳給 produce,其中,next 方法用于啟動(dòng)生成器,send 方法用于發(fā)送消息給 consumer,并切換到 consumer 執(zhí)行。consumer 通過 yield 獲取到消息,然后進(jìn)行處理,又通過 yield 返回消息給 produce,并轉(zhuǎn)到 produce 執(zhí)行,如此反復(fù)。執(zhí)行結(jié)果如下:

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK

小結(jié)

  • 子程序就是協(xié)程的一種特例
  • 協(xié)程的特點(diǎn)在于是一個(gè)線程內(nèi)執(zhí)行,沒有線程之間切換的開銷
  • 協(xié)程只有一個(gè)線程,不需多線程的鎖機(jī)制
  • 協(xié)程的切換由用戶自己管理和調(diào)度
  • 通過創(chuàng)建協(xié)程將異步編程同步化

參考資料