I/O多路轉接之select

系統提供select函數來實現多路複用輸入/輸出模型。

傳向select的參數告訴內核:

1)我們所關心的文件描述符。 

2)對每個描述符,我們所關心的狀態。(我們是要想從一個文件描述符中讀或者寫,還是關注一個描述符中是否出現異常)

3)我們要等待多長時間。(我們可以等待無限長的時間,等待固定的一段時間,或者根本就不等待)

從 select函數返回後,內核告訴我們以下信息:

1)已經做好準備的描述符的個數。

2)對於三種條件哪些描述符已經做好準備。(讀,寫,異常)

使用這些返回信息,就可調用相應的I/O函數(read/write或recv/send)

以阻塞方式監聽讀事件:




從代碼中可以看到,我們定義了一個fds數組,裏面存放了我們所關心的文件描述符。

數組的第一個元素是listen_sock,一旦監聽套接字準備好了,就accept,再將返回的文件描述符添加到fds中;

數組的其它元素是普通的socket(就是accept返回的文件描述符),如果select監聽到有普通socket準備好了,就說明有數據發過來了,就read。

需要注意的的是:

1)select的第一個參數是當前最大的文件描述符+1(其實就是select要檢查的文件描述符的數目,它的下標是從0開始的),所以,添加了文件描述符之後,記得要更新。

2)有client退出後,select就不需要再監聽它了,記得關閉文件描述符,並修改fds中的值。

代碼測試:


-------------------------------------------------------------------------------------------------------------------------------------------

使用select的優缺點:

優點:(1)相較於之前多線程的方法,使用select不用創建線程,更方便

            (2)select目前幾乎在所有的平臺上都支持,其良好跨平臺支持也是它的一個優點  

缺點:(1)能夠監視的文件描述符的數量存在最大限制,在Linux上一般爲1024,因爲它依賴於文件系統

          (2)select()所維護的文件描述符的數據結構,隨着文件描述符數量的增大,其複製的開銷也線性增長。

            (3)由於網絡響應時間的延遲使得大量TCP連接處於非活躍狀態,但調用select()會對所有socket進行一次線性掃描,這也會有一些開銷

發佈了62 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章