Python3協程

1.協程

  • 協程,又稱微線程,協程是一種用戶態的輕量級線程。
  • 協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。因此,協程能保留上一次調用時的狀態(即所有局部狀態的一個特定組合),每次過程重入時,就相當於進入上一次調用的狀態,也就是進入上一次離開時所處邏輯流的位置。

1.1 協程的好處

  • 無需線程上下文切換的開銷
  • 無需源自操作鎖定及同步的開銷
  • 方便切換控制流,簡化編程模型
  • 高併發+高擴展性+低成本:一個CPU支持上萬的協程都不是問題,所以很適合用於高併發處理

1.2 協程的缺點

  • 無法利用多核資源:協程的本質是單個線程,不能同時將單個CPU的多核利用上,需和進程配合才能運行在多CPU上
  • 進行阻塞操作(如IO)時會阻塞整個程序

1.3 yield支持下的協程

import time
import queue
def consumer(name):             #生成器
    print('------>starting.......')
    while True:
        new_baozi = yield
        print("[%s] is eating baozi %s" %(name, new_baozi))
        # time.sleep(1)

def producer():
    next(con)           #執行consumer代碼
    next(con2)
    n = 0
    while n < 5:
        n += 1
        print("\033[32;1m[producer]\033[0m is making baozi %s" % n)
        con.send(n)
        con2.send(n)

if __name__ == '__main__':
    con = consumer('c1')      #創建生成器對象
    con2 = consumer('c2')   #創建生成器對象
    p = producer()

1.4 gevent下的協

gevent是一個第三方庫,可以輕鬆通過gevent實現併發同步或異步編程,在gevent中用到的主要是greenlet,它是以c擴展模塊形式接入Python的輕量級協程。greenlet全部雲心那個在主程序操作系統的內部,但它們被協作式的調度

import greenlet
def test1():
    print(12)
    gr2.switch()
    print(34)
    gr2.switch()

def test2():
    print(56)
    gr1.switch()
    print(78)

gr1 = greenlet.greenlet(test1)      #創建一個greenlet對象
gr2 = greenlet.greenlet(test2)
gr1.switch()

 

 

import gevent
import time
def foo():
    print("Running in foo", time.ctime())
    gevent.sleep(1)           #模擬真正的IO阻塞
    print("Explicit context switch to foo again", time.ctime())

def bar():
    print("Explicit context to bar", time.ctime())
    gevent.sleep(2)
    print("Implicit context switch back to bar", time.ctime())

gevent.joinall([gevent.spawn(foo), gevent.spawn(bar)])

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章