I/O多路转接之select
生活随笔
收集整理的這篇文章主要介紹了
I/O多路转接之select
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
I/O多路轉接之select
文章目錄
- I/O多路轉接之select
- 一、五種IO模型
- 二、I/O多路轉接之select原理
一、五種IO模型
- 阻塞IO: 在內核將數據準備好之前, 系統調用會一直等待. 所有的套接字, 默認都是阻塞方式
- 非阻塞IO: 如果內核還未將數據準備好, 系統調用仍然會直接返回,并且返回EWOULDBLOCK錯誤碼.非阻塞IO往往需要程序員循環的方式反復嘗試讀寫文件描述符, 這個過程稱為輪詢.這對CPU來說是較大的浪費
- 信號驅動IO: 內核將數據準備好的時候, 使用SIGIO信號通知應用程序進行IO操作
- IO多路轉接: 雖然從流程圖上看起來和阻塞IO類似. 實際上最核心在于IO多路轉接能夠同時等待多個文件描述符的就緒狀態
- 異步IO: 由內核在數據拷貝完成時, 通知應用程序(而信號驅動是告訴應用程序何時可以開始拷貝數據
高級IO相關概念:
-
同步通信 vs 異步通信
-
同步和異步關注的是消息通信機制(注意和線程同步區分)
-
所謂同步,就是在發出一個調用時,在沒有得到結果之前,該調用就不返回. 但是一旦調用返回,就得 到返回值了;換句話說,就是由調用者主動等待這個調用的結果;
-
異步則是相反,調用在發出之后,這個調用就直接返回了,所以沒有返回結果; 換句話說,當一個異步過程調用發出后,調用者不會立刻得到結果; 而是在調用發出后,被調用者通過狀態、通知來通知調用者,或通過回調函數處理這個調用
-
阻塞 vs 非阻塞
-
阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.
-
阻塞調用是指調用結果返回之前,當前線程會被掛起. 調用線程只有在得到結果之后才會返回.
-
非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程
二、I/O多路轉接之select原理
- 1.函數原型
| nfds | 是需要監視的最大文件描述值+1 |
| fd_set *readfds | 需要檢測的可讀文件描述符的集合, |
| fd_set *writefds | 需要檢測的可寫文件描述符的集合 |
| fd_set *exceptfds | 需要檢測的異常文件描述符的集合; |
| struct timeval *timeout | 為結構timeval,用來設置select()的等待時間 |
- 函數返回值
-
2.理解fd_set結構
-
其實這個結構就是一個整型數組,更嚴格的說,是一個“位圖”,使用位圖中對應的位表示要監視的文件描述符
-
用來消除描述詞組 set中相關fd的位
- 用來測試描述詞組set中的相關fd的位是否為真;
- 用來設置描述詞組set中相關的位;
- 用來消除描述詞組set的全部位;
-
3.socket就緒條件
-
讀就緒:
1.socket內核中,接收緩沖區中的字節數,大于等于低水位標記SO_RCVLOWAT。此時就可以無阻塞的讀該文件描述符,并且返回值大于0;2.socket TCP通信中,對端關閉連接,此時對該socket讀,則返回0(四次揮手);3.監聽的socket上有新的連接請求;4.socket上有未處理的錯誤。 -
寫就緒:
1.socket內核中,發送緩沖區中的可用字節數(發送緩沖區的空閑位置大小),大于等于低水位標記SO_RCVLOWAT。此時可以無阻塞的寫,并且返回值大于0;2.socket的寫操作被關閉。對一個寫操作被關閉的socket進行寫操作,會觸發SIGPIPE信號;3.socket使用非阻塞connect連接成功或失敗之后;4.socket上有未讀取的錯誤; -
異常就緒:
socket上帶外數據。關于帶外數據,和TCP緊急模式相關(TCP協議頭中的緊急指針字段) -
4.理解select執行過程
理解select模型的關鍵在于理解fd_set,為說明方便,取fd_set長度為1字節,fd_set中的每一bit可以對應一個文件描述符fd。則1字節長的fd_set最大可以對應8個fd.
- (1)執行fd_set set; FD_ZERO(&set);則set用位表示0000,0000。
- (2)若fd=5,執行FD_SET(fd,&set);后set變為0001,0000(第5位置為1)
- (3)若再加入fd=2,fd=1,則set變為0001,0011
- (4)執行select(6,&set,0,0,0)阻塞等待
- (5)若fd=1,fd=2上都發生可讀事件,則select返回,此時set變為0000,0011。注意:沒有事件發生的fd=5被清空
- 5.select優缺點
select的特點
- 可監控的文件描述符個數取決與sizeof(fd_set)的值. 我這邊服務器上sizeof(fd_set)=512,每bit表示一個文件描述符,則我服務器上支持的最大文件描述符是512*8=4096.
- 將fd加入select監控集的同時,還要再使用一個數據結構array保存放到select監控集中的fd,
- 一是用于再select 返回后,array作為源數據和fd_set進行FD_ISSET判斷。
- 二是select返回后會把以前加入的但并無事件發生的fd清空,則每次開始select前都要重新從array取得 fd逐一加入(FD_ZERO最先),掃描array的同時取得fd最大值maxfd,用于select的第一個參數。
select缺點
- 每次調用select, 都需要手動設置fd集合, 從接口使用角度來說也非常不便.
- 每次調用select,都需要把fd集合從用戶態拷貝到內核態,這個開銷在fd很多時會很大
- 同時每次調用select都需要在內核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大
- select支持的文件描述符數量太小
- 6.select實現tcp服務器(支持多用戶)
總結
以上是生活随笔為你收集整理的I/O多路转接之select的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络基础(三)
- 下一篇: IO多路转接之poll