i/o復用典型地用在下列網路應用場合:
1.當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用i/o復用。
2.乙個客戶同時處理多個套介面是可能的,但是很少出現。
3. 如果乙個tcp伺服器既要處理監聽套介面,又要處理已連線套介面,一般也要用到i/o復用。
4. 如果乙個伺服器既要處理tcp,又要處理udp,一般也要使用i/o復用。
5. 如果乙個伺服器要處理多個服務或者多個協議,一般要使用i/o復用。
select函式
select()系統呼叫可以使程序檢測同時等待的多個i/o裝置,當沒有裝置準備好時,select()阻塞,其中任一裝置準備好時,select()就返回。
#include select.h>#includeintselect(int
maxfd, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
const
struct timeval *timeout);
select的第乙個引數是檔案描述符集中要被檢測的位元數,這個值必須至少比待檢測的最大檔案描述符大1;引數readfds指定了被讀監控的檔案描述符集;引數writefds指定了被寫監控的檔案描述符集;而引數exceptfds指定了被例外條件監控的檔案描述符集。引數timeout起了定時器的作用:到了指定的時間,無論是否有裝置準備好,都返**用。
timeval的結構定義如下:
struct timeval
timeout取不同的值,該呼叫就表現不同的性質:
1.timeout為0,呼叫立即返回;
2.timeout為null,select()呼叫就阻塞,直到知道有檔案描述符就緒;
3.timeout為正整數,就是一般的定時器。
select呼叫返回時,除了那些已經就緒的描述符外,select將清除readfds、writefds和exceptfds中的所有沒有就緒的描述符。select的返回值有如下情況:
1.正常情況下返回就緒的檔案描述符個數;
2.經過了timeout時長後仍無裝置準備好,返回值為0;
3.如果select被某個訊號中斷,它將返回-1並設定errno為eintr。
4.如果出錯,返回-1並設定相應的errno。
系統提供了4個巨集對描述符集進行操作:
#include select.h>#includevoid fd_set(int fd, fd_set *fdset);
void fd_clr(int fd, fd_set *fdset);
void fd_isset(int fd, fd_set *fdset);
void fd_zero(fd_set *fdset);
巨集fd_set設定檔案描述符集fdset中對應於檔案描述符fd的位(設定為1),巨集fd_clr清除檔案描述符集 fdset中對應於檔案描述符fd的位(設定為0),巨集fd_zero清除檔案描述符集fdset中的所有位(既把所有位都設定為0)。使用這3個巨集在呼叫select前設定描述符遮蔽位,在呼叫select後使用fd_isset來檢測檔案描述符集fdset中對應於檔案描述符fd的位是否被設定。
select的使用方法:
1. 將要監控的檔案新增到檔案描述符集
2. 呼叫select開始監控
3. 判斷檔案是否發生變化。
fd_zero(&fds); //清空集合
fd_set(fd1,&fds); //設定描述符
fd_set(fd2,&fds); //設定描述符
maxfdp=fd1+1; //描述符最大值加1,假設fd1>fd2
switch(select(maxfdp,&fds,null,null,&timeout))
case -1: exit(-1);break; //select錯誤,退出程式
case 0:break;
default:if(fd_isset(fd1,&fds)).... //測試fd1是否可讀
可執行源**:
#include#include#include
#include
#include
#include
#include
#define timeout 5
#define buf_len 1024
int max(int a,int
b)int main(void
)
else
if(!ret)
if (fd_isset(stdin_fileno, &readfds))
if(len)
}if (fd_isset(fd_open, &readfds))
if(len)
}fprintf(stderr,""
);
return1;
}
gcc編譯通過,可以自行測試執行,本程式測試了兩個描述符,乙個標準輸入,乙個是檔案描述符。
pselect函式
#include select.h>#include#include
int pselect(int maxfdp1, fd_set * readset, fd_set * writeset, fd_set * exceptset, const
struct timespec * timeout, const sygset_t *sigmask);
//返回: 準備好描述字的個數, 0-超時 -1-出錯
poll函式
poll提供了與select相似的功能,但當涉及到流裝置時,它還提供了附加資訊。
#include int poll(struct pollfd * fdarray, unsigned long nfds, int timeout); //返回: 準備好描述字的個數, 0-超時, -1-出錯
I O多路復用
一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...
i o多路復用
最常見的i o多路復用就是 select poll epoll了,下面說說他們的一些特點和區別吧。select 可讀 可寫 異常三種檔案描述符集的申明和初始化。fd set readfds,writefds,exceptionfds fd zero readfds fd zero writefds ...
I O多路復用
我們都知道unix like 世界裡,一切皆檔案,而檔案是什麼呢?檔案就是一串二進位製流而已,不管socket,還是fifo 管道 終端,對我們來說,一切都是檔案,一切都是流。在資訊 交換的過程中,我們都是對這些流進行資料的收發操作,簡稱為i o操作 input and output 往流中讀出資料...