python 備忘(協程)
阿新 • • 發佈:2020-10-20
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()方法的引數是一個協程物件列表,等待所有的協程都執行完成後退出