協程是用戶相互協作的線程,又稱微線程,本身還是線程。
線程是系統級別的,它們是由操作系統調度;協程是程序級別的,由程序員根據需要自己調度。我們把一個線程中的一個個函數叫做子程序,那么子程序在執行過程中可以中斷去執行別的子程序;別的子程序也可以中斷回來繼續執行之前的子程序,這就是協程。也就是說同一線程下的一段代碼<1>執行着執行着就可以中斷,然后跳去執行另一段代碼,當再次回來執行代碼塊<1>的時候,接着從之前中斷的地方開始執行。
優點:
並沒有說協程就一定不加鎖,協程本身的某些功能實現也是通過線程池實現的;就算沒有用到其他線程,假如一個操作需要連續性地完成,那么也是需要借助鎖的概念。asyncio 和 gevent 庫中都有實現 threading 下的一些同步機制,比如 Lock、Semaphore 等,雖然和 threading 的底層的實現不同,但是同樣起到了保證一些操作順序、不會被打斷地執行。
Gevent: (實現遇到IO自動切換)
Gevent 是一個第三方庫,可以輕松通過gevent實現並發同步或異步編程,在gevent中用到的主要模式是Greenlet, 它是以C擴展模塊形式接入Python的輕量級協程。 Greenlet全部運行在主程序操作系統進程的內部,但它們被協作式地調度。
gevent是一個基於協程(coroutine)的Python網絡函數庫,通過使用greenlet提供了一個在libev事件循環頂部的高級別並發API。
主要特性有以下幾點:
基於libev的快速事件循環,Linux上面的是epoll機制
基於greenlet的輕量級執行單元
API復用了Python標准庫里的內容
支持SSL的協作式sockets
可通過線程池或c-ares實現DNS查詢
通過monkey patching功能來使得第三方模塊變成協作式
Monket patching
Python的運行環境允許我們在運行時修改大部分的對象,包括模塊、類甚至函數。雖然這樣做會產生“隱式的副作用”,而且出現問題很難調試,但在需要修改Python本身的基礎行為時,Monkey patching就派上用場了。Monkey patching能夠使得gevent修改標准庫里面大部分的阻塞式系統調用,包括socket,ssl,threading和select等模塊,而變成協作式運行。
Semaphore和BoundedSemphore 都是信號量類, 有進/線/協程獲得信號量時(即acquire())計數器-1,釋放信號量時(release())技術器+1,計數器為0的時候其他線/進/協程就被阻塞無法獲得信號量。當計數器為設定好的上限的時候BoundedSemaphore就無法進行release()操作,Semaphore沒有這個限制。
參考文獻:https://www.cnblogs.com/zhangyux/p/6195860.html