1. 程式人生 > 實用技巧 >python 備忘(協程)

python 備忘(協程)

1.yield

import time

def work1():
    # 迴圈列印數字1
    while True:
        print("-----1-----")
        # yield可以暫時掛起該函式,跳轉到呼叫該函式的下方
        yield
        # 延遲一秒以便觀察
        time.sleep(1)

def work2():
    while True:
        print("-----2-----")
        yield
        time.sleep(1)

th1 = work1()
th2 = work2()

while True:
    # 喚醒被掛起的函式
    next(th1)
    next(th2)

yield 是類似於return的關鍵字,不同的是,return關鍵字是直接結束了函式的執行。而yield 可以通過呼叫 send(), next() 讓函式繼續從yield關鍵字下一條語句繼續執行。
send()函式的用法 是可以傳參的,send(param) 。即傳一個引數給yield生成器。
next() 函式和send()不同的是它不傳參。

2.greenlet

import time
import greenlet


def work1():
    # 迴圈列印字串
    while True:
        print("----1----")
        # 啟動th2
        th2.switch()
        time.sleep(1)

def work2():
    # 迴圈列印字串
    while True:
        print("----2----")
        # 啟動th1
        th1.switch()
        time.sleep(1)

# 建立攜程
th1 = greenlet.greenlet(work1)
th2 = greenlet.greenlet(work2)
# 啟動攜程
th1.switch()

greenlet不是一種真正的併發機制,而是在同一執行緒內,在不同函式的執行程式碼塊之間切換
當出現阻塞時,就顯式切換到沒有被阻塞的程式碼段執行,直到另一端程式碼再顯示的切換到本段程式碼時,這段程式碼才會繼續執行。

3.gevent

import gevent
import time

def work1():
    # 迴圈列印
    while True:
        print("----1----")
        # 破解sleep 使sleep不再阻塞
        gevent.sleep(1)

def work2():

    while True:
        print("----2----")
        gevent.sleep(1)

# 建立並開始執行攜程
th1 = gevent.spawn(work1)
th2 = gevent.spawn(work2)
# 阻塞等待攜程結束
gevent.joinall([th1,th2])

gevent的核心greenlet,並試用 epoll機制使執行緒實現自動切換,並保證始終有greenlet在執行,而不是等待io。
gevent.spawn()方法會建立並執行一個新的greenlet協程物件。
gevent.joinall()方法的引數是一個協程物件列表,等待所有的協程都執行完成後退出