伺服器IO多路複用的select和poll的區別以及監聽套接字select函式的四個宏操作

小楠同志發表於2024-06-10

目錄
  • 知識補給站
    • 對檔案描述符集合操作的四個宏操作
    • 伺服器IO多路複用中的select和poll的區別

知識補給站

對檔案描述符集合操作的四個宏操作

對檔案描述符集合操作的四個宏操作在select函式中起著關鍵的作用,它們用於初始化、新增、刪除和檢查檔案描述符集合中的元素。這四個宏為: FD_ZERO、FD_SET、FD_CLR、FD_ISSET:

FD_ZERO(fd_set *fdset)

  • 功能:清空檔案描述符集合。

  • 引數:一個指向fd_set型別變數的指標。

  • 作用:將fdset指向的檔案描述符集合中的所有位都設定為0,確保集合中沒有包含任何檔案描述符。

FD_SET(int fd, fd_set *fdset)

  • 功能:將一個檔案描述符新增到檔案描述符集合中。
  • 引數:一個整數fd,代表要新增的檔案描述符;一個指向fd_set型別變數的指標。
  • 作用:將fdset指向的檔案描述符集合中對應於fd的位設定為1,表示該集合包含檔案描述符fd

FD_CLR(int fd, fd_set *fdset)

  • 功能:從檔案描述符集合中刪除一個檔案描述符。
  • 引數:一個整數fd,代表要刪除的檔案描述符;一個指向fd_set型別變數的指標。
  • 作用:將fdset指向的檔案描述符集合中對應於fd的位設定為0,表示該集合不再包含檔案描述符fd

FD_ISSET(int fd, fd_set *fdset)

  • 功能:檢查檔案描述符集合中是否包含某個檔案描述符。
  • 引數:一個整數fd,代表要檢查的檔案描述符;一個指向fd_set型別變數的指標。
  • 返回值:如果fdset指向的檔案描述符集合中包含fd,則返回非零值(通常為1);否則返回0。
  • 作用:用於在select函式返回後,檢查哪些檔案描述符已經就緒(可讀、可寫或存在異常條件)。

伺服器IO多路複用中的select和poll的區別

  1. 資料結構差異:
    (1)select:使用點陣圖(bitmap)資料結構來儲存被監聽的檔案描述符集合。這種資料結構在檔案描述符數量較少時效率較高,但受限於點陣圖的大小,通常能監聽的檔案描述符數量有限(通常在1024個左右,取決於系統和庫的實現)。
    (2)poll:使用結構體陣列(如pollfd)來儲存被監聽的檔案描述符及其相關事件。這種資料結構允許監聽更多的檔案描述符,因為它不受點陣圖大小的限制。
  2. 事件繫結:
    (1)select:沒有將檔案描述符和事件進行繫結。每次呼叫select時,都需要透過三個獨立的檔案描述符集合來指定要監聽的可讀、可寫和異常事件。
    (2)poll:將檔案描述符和事件直接繫結在pollfd結構體中,這使得程式設計介面更為簡潔。在呼叫poll時,只需傳遞一個包含所有監聽資訊的pollfd陣列即可。
  3. 資料複製:
    (1)select:在每次呼叫時,都需要將檔案描述符集合從使用者空間複製到核心空間,並在返回時將結果從核心空間複製回使用者空間。這種頻繁的資料複製在檔案描述符數量較多時會導致效能下降。
    (2)poll:同樣存在資料複製的問題,但由於poll使用結構體陣列而不是點陣圖,因此在某些情況下可能具有更高的效率。
  4. 時間複雜度:
    (1)select:在核心中無差別地遍歷每個檔案描述符,時間複雜度為O(n)。當檔案描述符數量較大時,效能會受到顯著影響。
    (2)poll:與select類似,也需要在核心中遍歷每個檔案描述符。但由於poll允許監聽更多的檔案描述符,因此在某些情況下可能具有更好的效能。
  5. 可重用性:
    (1)select:每次呼叫select時,都需要重新建立和設定檔案描述符集合。這可能導致額外的程式設計開銷。
    (2)poll:由於poll將檔案描述符和事件繫結在結構體中,因此可以在多次呼叫之間重用相同的pollfd陣列,從而減少了程式設計開銷。

相關文章