單執行緒實現併發——協程,gevent模組
阿新 • • 發佈:2018-12-18
一 併發的本質
1 切換
2 儲存狀態
二 協程的概念
協程,又稱微執行緒,纖程。英文名Coroutine。單執行緒下實現併發,使用者從應用程式級別控制單執行緒下任務的切換,注意一定是遇到I/O才切。
協程的特點在於是一個執行緒執行,那和多執行緒比,協程有何優勢?
最大的優勢就是協程極高的執行效率。因為子程式切換不是執行緒切換,而是由程式自身控制,因此,沒有執行緒切換的開銷,和多執行緒比,執行緒數量越多,協程的效能優勢就越明顯。
第二大優勢就是不需要多執行緒的鎖機制,因為只有一個執行緒,也不存在同時寫變數衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多執行緒高很多。
因為協程是一個執行緒執行,那怎麼利用多核CPU呢?最簡單的方法是多程序+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的效能。
三 gevent模組
gevent是一個基於協程的Python網路庫。
需要匯入猴子補丁。
方法:
g1=gevent.spawn(func,):提交任務。 生成g1,是Greenlet類
gevent.sleep():睡
gevent.joinall(可迭代物件):阻塞,知道所有選中的任務執行完畢。
g1.join()
g1.value 獲取由func函式生成Greenlet類的返回值。
![複製程式碼](https://common.cnblogs.com/images/copycode.gif)
import gevent from gevent import monkey;monkey.patch_all() from threading import current_thread import time def foo(): print('%s is running ' % current_thread().getName()) time.sleep(1) print('%s is done '%current_thread().getName()) def bar(): print('%s is running ' % current_thread().getName()) time.sleep(2) print('%s is done ' % current_thread().getName()) g1=gevent.spawn(foo) g2=gevent.spawn(bar) print('g1',g1) print('g2',g2) # g1.join() # g2.join() gevent.joinall([g1,g2])
![複製程式碼](https://common.cnblogs.com/images/copycode.gif)
輸出:
g2 <Greenlet at 0x26d7aff0898: bar> DummyThread-1 is running DummyThread-2 is running DummyThread-1 is done DummyThread-2 is done