日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python异步编程原理篇之协程的IO

發布時間:2024/1/21 python 53 coder
生活随笔 收集整理的這篇文章主要介紹了 Python异步编程原理篇之协程的IO 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

協程的IO

asyncio 作為實現異步編程的庫,任務執行中遇到系統IO的時能夠自動切換到其他任務。協程使用的IO模型是IO多路復用。asyncio 低階API 一篇中提到過 “以Linux系統為例,IO模型有阻塞,非阻塞,IO多路復用等。asyncio 常用的是IO多路復用模型的epoolkqueue”。本篇就介紹一下IO多路復用技術以及操作系統的IO,為后續內容做一個鋪墊。

什么是IO

根據馮.諾依曼結構,它將計算機分成分為5個部分:運算器、控制器、存儲器、輸入設備、輸出設備。
涉及計算機核心與其他設備間數據遷移的過程就是IO

常見的IO包括:文件的讀寫、網絡請求。
以文件讀寫為例,一個應用程序讀一個文件。一個應用程序就是一個進程,操作系統為每一個進程分配的內存分為兩個部分,分別是用戶空間和內核空間。以32位系統為例,用戶空間分配3GB,內核空間分為1GB。IO操作因為都是和硬件設備交互,所以不能讓用戶進程直接操作,而是需要進程調用操作提供提供的API來完成。

應用程序讀一個文件的流程是:

  1. 應用程序調用系統提供讀文件的命令
  2. 系統將磁盤中文件內容讀取到內核空間
  3. 系統將文件內容從內核空間拷貝的用戶空間
  4. 應用程序讀取用戶空間中的文件內容

從文件IO總結IO的基本流程為:

總結來看,IO操作的基本流程是:

  1. 應用程序發起IO調用
  2. 操作系統完成IO操作

阻塞IO模型

阻塞IO模型就是應用程序發起IO調用之后一直阻塞等待,一直等到數據從內核空間拷貝用戶空間,此次調用才算完成。
流程圖如下:

存在問題:
如果內核數據一直沒準備好,那用戶進程將一直阻塞,CPU空轉而浪費時間。并發大的情況下將導致進程數量變大,限制并發數量。

非阻塞IO模型

應用程序發起IO調用,如果內核空間數據還沒讀取完成,可以先返回錯誤信息給用戶進程,讓它不需要等待,而是通過輪詢的方式再來請求。這就是非阻塞IO,流程圖如下:

非阻塞IO的流程如下:

  • 應用進程向操作系統內核,發起讀取數據。
  • 操作系統內核數據沒有準備好,立即返回錯誤碼。
  • 應用程序輪詢調用,繼續向操作系統內核發起讀取數據。
  • 操作系統內核空間讀取數據完成,從內核緩沖區拷貝到用戶空間。
  • 完成調用,返回成功提示。

存在問題:
它相對于阻塞IO,雖然大幅提升了性能,但是它依然存在性能問題,即頻繁的輪詢,導致頻繁的系統調用,同樣會消耗大量的CPU資源。

IO多路復用模型

非阻塞IO的問題

非阻塞IO模型下并發情況下應用程序可能會發送上千次請求,如果每一次請求的IO都需要輪詢獲取結果,那么應用就需要創建上千個線程去輪詢監聽數據是否拷貝完成。

這么多的線程不斷調用系統函數 recvfrom 請求數據,首先服務器不能支持這么多請求,其次這種方式太浪費資源了,線程是我們操作系統的寶貴資源,大量的線程用來去讀取數據了,那么就意味著能做其它事情的線程就會少。如何解決這個問題呢?使用IO多路復用可以將輪詢監聽的線程降低到1個。

IO多路復用介紹

IO多路復用的原理
可以由一個線程監控多個網絡請求,當有數據準備好之后再通知對應的線程去讀取數據。這樣就可以只需要一個線程完成數據是否就緒狀態的查詢。通過復用一個輪詢的線程節省出大量的線程資源出來,這個就是IO復用模型的思路。

IO多路復用的流程

  1. 應用程序調用IO請求返回一個文件描述符
  2. IO多路復用的函數(select、poll、epoll)同時監控多個文件描述符
  3. 當某一個文件描述符的狀態變成就緒時,IO多路復用函數通知對應應用程序
  4. 應用程序讀取文件,數據從內核空間拷貝的用戶空間,完成數據IO

IO多路復用使用的函數有三種,分別是:select、poll、epoll。三者在實現上有一些區別。IO多路復用實現的核心思想是監聽文件描述符fd的狀態,當fd狀態就緒時通知對應的應用讀取數據。

select

應用進程通過調用select函數,可以同時監控多個文件描述符。在select函數監控的fd中,只要有任何一個數據狀態準備就緒了,select函數就會返回可讀狀態,這時應用進程再發起recvfrom請求去讀取數據。

select缺點:

  • 監聽的IO最大連接數有限,在Linux系統上一般為1024。
  • select函數是通過遍歷fdset,找到就緒的描述符fd。遍歷的時間性能消耗較大

poll

由于select存在連接數限制,所以后來又提出了poll。poll模型里面通過使用鏈表的形式來保存自己監控的fd信息,連接數限制問題。

缺點:
select和poll一樣,還是需要通過遍歷文件描述符來獲取已經就緒的socket。如果同時連接的大量客戶端在一時刻可能只有極少處于就緒狀態,伴隨著監視的描述符數量的增長,效率也會線性下降。

epoll

epoll并不是像select一樣去遍歷事件列表逐個輪詢的監控fd的事件狀態,而是事先就建立了fd與之對應的回調函數,當事件激活后主動回調將fd加入到就緒鏈表中,這也就避免了遍歷事件列表的這個操作。
這里去掉了遍歷文件描述符的低性能操作,而是采用監聽事件回調的的機制。這就是epoll的亮點。

小結

需要注意的是IO多路復用也是阻塞的IO,只不過它能并發處理的IO效率更高。

信號驅動模型

信號驅動IO不再用主動詢問的方式去確認數據是否就緒,而是向內核發送一個信號(調用sigaction的時候建立一個SIGIO的信號),然后應用用戶進程可以去做別的事,不用阻塞。當內核數據準備好后,再通過SIGIO信號通知應用進程,數據準備好后的可讀狀態。應用用戶進程收到信號之后,立即調用recvfrom,去讀取數據。

信號驅動IO模型,在應用進程發出信號后,是立即返回的,不會阻塞進程。它已經有異步操作的感覺了。但是數據復制到應用緩沖的時候,應用進程還是阻塞的。
回過頭來看下,不管是非阻塞IO、IO多路復用還是信號驅動,在數據從內核復制到應用緩沖的時候,都是阻塞的。

異步IO模型

非阻塞IO、IO多路復用還是信號驅動在數據從內核復制到應用緩沖的時候,都是阻塞的,因此都不是真正的異步。
異步IO實現了IO全流程的非阻塞,就是應用進程發出系統調用后,是立即返回的,但是立即返回的不是處理結果,而是表示提交成功類似的意思。等內核數據準備好,將數據拷貝到用戶進程緩沖區,發送信號通知用戶進程IO操作執行完畢。

異步IO的原理很簡單,只需要向內核發送一次請求,就可以完成數據狀態詢問和數據拷貝的所有操作,并且不用阻塞等待結果。

同步、異步、阻塞、非阻塞總結

相關術語:

  • 同步阻塞(blocking-IO)簡稱BIO
  • 同步非阻塞(non-blocking-IO)簡稱NIO
  • 異步非阻塞(asynchronous-non-blocking-IO)簡稱AIO

參考文章:
https://zhuanlan.zhihu.com/p/439770090

總結

以上是生活随笔為你收集整理的Python异步编程原理篇之协程的IO的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。