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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IO模型(select, poll, epoll的区别和原理)

發布時間:2025/3/21 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IO模型(select, poll, epoll的区别和原理) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考《unix網絡編程》

參考http://blog.csdn.net/blueboy2000/article/details/4485874

參考http://blog.csdn.net/suxinpingtao51/article/details/46314097


五種I/O模型

  • 阻塞I/O:應用程序調用一個IO函數,導致應用程序阻塞,如果數據已經準備好,從內核拷貝到用戶空間,否則一直等待下去

  • 非阻塞I/O:

  • I/O復用(select和poll)

  • 信號驅動I/O(SIGIO)

  • 異步I/O(Posix.1的aio_系列函數)

  • 一個輸入操作通常包括兩個階段: 1.等待數據準備好 2.從內核向進程復制數據 對于一個套接字上的輸入操作,第一步通常涉及等待數據從網絡中到達,當所有等待分組到達時,它被復制到內核中的某個緩沖區。第二步就是將數據從內核緩沖區復制到應用進程的緩沖區
    阻塞I/O應用程序調用一個IO函數,導致應用程序阻塞,如果數據已經準備好,從內核拷貝到用戶空間,否則一直等待下去


    非阻塞I/O模型?
    我們把一個套接口設置為非阻塞就是告訴內核,當所請求的I/O操作無法完成時,不要將進程睡眠,而是返回一個錯誤。這樣我們的I/O操作函數將不斷的測試數據是否已經準備好,如果沒有準備好,繼續測試,直到數據準備好為止。在這個不斷測試的過程中,會大量的占用CPU的時間
    當一個應用程序像這樣對一個非阻塞描述符循環調用recvfrom時,我們稱之為輪循(polling)
    總結:阻塞I/O模式下,雖然不會占用大量的CPU時間,一個線程只能處理一個流的I/O事件。如果想要同時處理多個流,要么多進程(fork),要么多線程(pthread_create),很不幸這兩種方法效率都不高。于是再來考慮非阻塞忙輪詢的I/O方式,我們發現我們可以同時處理多個流了(把一個流從阻塞模式切換到非阻塞模式再此不予討論): [cpp] view plain copy
  • <span?style="font-family:Microsoft?YaHei;font-size:14px;">while?true?{??
  • ????for?i?in?stream[];?{??
  • ????????if?i?has?data??
  • ????????read?until?unavailable??
  • ????}??
  • }</span>??
  • ? ? 我們只要不停的把所有流從頭到尾問一遍,又從頭開始。這樣就可以處理多個流了,但這樣的做法顯然不好,因為如果所有的流都沒有數據,那么只會白白浪費CPU。 為了避免CPU空轉,可以引進了一個代理(一開始有一位叫做select的代理,后來又有一位叫做poll的代理,不過兩者的本質是一樣的)。這個代理比較厲害,可以同時觀察許多流的I/O事件,在空閑的時候,會把當前線程阻塞掉,當有一個或多個流有I/O事件時,就從阻塞態中醒來,于是我們的程序就會輪詢一遍所有的流(于是我們可以把“忙”字去掉了) [cpp] view plain copy
  • <span?style="font-family:Microsoft?YaHei;font-size:14px;">while?true?{??
  • ????select(streams[])??
  • ????for?i?in?streams[]?{??
  • ????????if?i?has?data??
  • ????????read?until?unavailable??
  • ????}??
  • }</span>??
  • 于是,如果沒有I/O事件產生,我們的程序就會阻塞在select處。但是依然有個問題,我們從select那里僅僅知道了,有I/O事件發生了,但卻并不知道是那幾個流(可能有一個,多個,甚至全部),我們只能無差別輪詢所有流,找出能讀出數據,或者寫入數據的流,對他們進行操作。即使用select,我們有O(n)的無差別輪詢復雜度,同時處理的流越多,沒一次無差別輪詢時間就越長。
    epoll可以理解為event poll,不同于忙輪詢和無差別輪詢,epoll之會把哪個流發生了怎樣的I/O事件通知我們。此時我們對這些流的操作都是有意義的。(復雜度降低到了O(1))

    I/O復用模型?
    I/O復用模型會用到select或者poll函數,這兩個函數也會使進程阻塞,但是和阻塞I/O所不同的的,這兩個函數可以同時阻塞多個I/O操作。而且可以同時對多個讀操作,多個寫操作的I/O函數進行檢測,直到有數據可讀或可寫時,才真正調用I/O操作函數。?

    我們阻塞于select調用,等待數據報套接字變為可讀。當select返回套接字可讀這一條件時,我們調用recefrom把所有讀數據報復制到應用進程緩沖區。
    信號驅動I/O模型?
    我們也可以用信號,讓內核在描述符就緒時發送SIGIO信號通知我們。通過sigaction系統調用安裝一個信號處理函數。該系統調用將立即返回,我們的進程繼續工作,也就是說它沒有被阻塞。當數據報準備好讀取時,內核就為該進程產生一個SIGIO信號。我們隨后既可以在信號處理函數中調用recvfrom讀取數據報,并通知主循環數據已經準備好待處理。
    優勢:等待數據報到達期間進程不被阻塞。主循環可以繼續執行,只要等待來自信號處理函數的通知:既可以是數據已準備好被處理,也可以是數據報已準備好被讀取。

    異步I/O模型?
    告知內核啟動某個操作,并讓內核在整個操作(包括將內核復制到我們自己的緩沖區)完成后通知我們。 與信號驅動模型的主要區別在于:信號驅動式I/O是由內核通知我們何時可以啟動一個I/O操作,而異步模型是由內核通知我們I/O操作何時完成。

    調用aio_read函數,告訴內核描述字,緩沖區指針,緩沖區大小,文件偏移以及通知的方式,然后立即返回。當內核將數據拷貝到緩沖區后,再通知應用程序。?

    各種I/O模型的對比:

    同步I/O和異步I/O對比:同步I/O操作導致請求阻塞(前4種模型是是同步I/O模型),直到I/O操作完成;異步I/O操作不導致請求進程阻塞。

    http://www.cnblogs.com/Anker/p/3265058.html

    select, poll, epoll區別以及原理

    介紹epoll中函數,以及它們的使用, ET和LT是區別

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的IO模型(select, poll, epoll的区别和原理)的全部內容,希望文章能夠幫你解決所遇到的問題。

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