I O復用的方式之一select系統呼叫

2021-09-12 12:02:30 字數 1289 閱讀 1461

來自《linux高效能伺服器程式設計》

i/o復用是用來解決監聽多個描述符上是否有就緒事件的系統呼叫。具體包含以下幾種情況:客戶端程式同時處理多個監聽套接字socket;客戶端要同時處理使用者輸入和網路連線;tcp伺服器要同時處理多個描述符;伺服器要同時處理tcp請求和udp請求;伺服器要同時監聽多個介面等。

select系統呼叫:在一段時間內,監聽使用者感興趣的檔案描述符上的可讀,可寫,異常等事件。

select系統呼叫的原型如下:

#include

int select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * execptfds,struct timeval * timeout);

nfds表示被監聽的檔案描述符的總數。通常被設定為select監聽的所有檔案描述符中的最大值加一,因為檔案描述符是從0開始計數的;接下來的三個引數分別表示可讀,可寫和異常事件對應的檔案描述符集合。他們是fd_set結構體指標型別。fd_set結構體僅包含乙個整型陣列,該陣列的每個元素的每一位(bit)標記乙個檔案描述符。fd_set能容納的檔案描述符數量由fd_setsize指定,這就限制了select能同時處理的檔案描述符的總數。timeout引數用來設定select的超時時間。他是乙個timeval結構體的指標,使用指標是因為核心將修改它以告訴select等待了多少時間。但是呼叫失敗時timeout的值是不確定的。

select成功時返回就緒檔案描述符的總數,如果在超時時間內沒有任何檔案描述符就緒,select返回0,失敗時select返回-1.

下列情況表示socket可讀:

socket核心緩衝區接受到的位元組數大於或等於其低水位標記so_rcvlowat。此時我們可以無阻塞的讀該socket,並且讀運算元返回值大於零;socket通訊的對方關閉連線,此時對該socket的讀運算元將返回0(recv也返回零);監聽socket上有新的連線請求(別人connect時);socket上有未處理的錯誤,此時我們可以用getsockopt來讀取和清除錯誤。

下列情況下socket可寫:

socket核心緩衝區傳送的位元組數大於或等於其低水位標記so_sndlowat。此時我們可以無阻塞的寫該socket,並且寫運算元返回值大於零;socket的寫操作被關閉,對寫操作被關閉的socket執行寫操作將觸發乙個sigpipe訊號;socket使用非阻塞connect連線成功或者失敗之後;socket上有未處理的錯誤,此時我們可以用getsockopt來讀取和清除錯誤。

下列情況socket異常:socket上接收到帶外資料。

select實現I O復用

select 系統提供select函式來實現多路復用輸入 輸出模型。select系統呼叫是用來讓我們的程式監視多個檔案控制代碼的狀態變化的。程式會停在select這裡等待,直到被監視的檔案控制代碼有乙個或 多個發生了狀態改變。關於檔案控制代碼,其實就是乙個整數,我們最熟悉的控制代碼是0 1 2三 個...

I O復用 select 學習

最近在學習網路程式設計,覺得select這塊的知識點確實比較難以理解,在學習socket網路通訊機制時,只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式,所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,...

Linux的三種I O復用方式 select

select poll epollselect的原型是 int select int maxfd,fd set readfds,fd set,fd set writefds,fd set exceptfds,struct timeval timeout maxfd 監聽的最大檔案描述符的值 1 輪詢...