I O多路復用

2022-02-13 14:04:16 字數 3031 閱讀 9283

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>#include 

intselect(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>#include 

void 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 往流中讀出資料...