關於協程及其鎖的一些認識


協程是用戶相互協作的線程,又稱微線程,本身還是線程。

線程是系統級別的,它們是由操作系統調度;協程是程序級別的,由程序員根據需要自己調度。我們把一個線程中的一個個函數叫做子程序,那么子程序在執行過程中可以中斷去執行別的子程序;別的子程序也可以中斷回來繼續執行之前的子程序,這就是協程。也就是說同一線程下的一段代碼<1>執行着執行着就可以中斷,然后跳去執行另一段代碼,當再次回來執行代碼塊<1>的時候,接着從之前中斷的地方開始執行。

優點:

  1. 極高的執行效率,因為子程序切換而不是線程切換,沒有了線程切換的開銷;
  2. 不需要多線程的鎖機制,因為只有一個線程在執行;

並沒有說協程就一定不加鎖,協程本身的某些功能實現也是通過線程池實現的;就算沒有用到其他線程,假如一個操作需要連續性地完成,那么也是需要借助鎖的概念。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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM