解決程序或執行緒阻塞到某個 i/o 系統呼叫而出現的技術,使程序不阻塞於某個特定的 i/o 系統調
1.當客戶處理多個描述符(通常是互動式輸入、網路套接字)時,必須使用i/o復用。2.tcp伺服器既要處理監聽套接字,又要處理已連線套接字,一般要使用i/o復用。
3.如果乙個伺服器既要處理tcp又要處理udp,一般要使用i/o復用。
4.如果乙個伺服器要處理多個服務或多個服務時,一般要使用
i/o復用。
select、poll
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);功能:輪詢掃瞄多個描述符中的任一描述符是否發生響應,或經過一段時間後喚醒
引數:
引數名稱
說明maxfd
指定要檢測的描述符的範圍
所檢測描述符最大值+1
readset
可讀描述符集
監測該集合中的任意描述符是否有資料可讀
writeset
可寫描述符集
監測該集合中的任意描述符是否有資料可寫
exceptset
異常描述符集
監測該集合中的任意描述符是否發生異常
timeout
超時時間
超過規定時間後喚醒
返回值:
0:超時標頭檔案:-1:出錯
>0:準備好的檔案描述符數量
超時時間#include
#include
:
//該結構體表示等待超時的時間
struct timeval;
//比如等待10.2秒
struct timeval timeout;
timeoout.tv_sec =
10;timeoout.tv_usec =
200000;
//將select函式的timeout引數設定為null則永遠等待
select()函式能對多個檔案描述符進行監測,如果乙個引數對應乙個描述符,那麼select函式的4個引數最多能監測4個檔案描述,那他如何實現對多個檔案描述符的監測的呢?大家想一想檔案描述符基本具有3種特性(讀、寫、異常),如果我們統一將監測可讀
的描述符放入可讀集合(readset),監測可寫的描述符放入可寫集合(writeset),監測異常的描述符放入異常集合(exceptset)。然後將這3個集合傳給select函式,是不是就可監測多個描述符呢.
如何將某個描述符加入到特定的集合中呢?這時就需要了解下面的集合操作函式
/初始化描述符集
void
fd_zero(fd_set *fdset);
//將乙個描述符新增到描述符集
void
fd_set(int fd, fd_set *fdset);
//將乙個描述符從描述符集中刪除
void
fd_clr(int fd, fd_set *fdset);
//檢測指定的描述符是否有事件發生
intfd_isset(int fd, fd_set *fdset);
例子:檢測 0、4、5 描述符是否準備好讀
while(
1)if(fd_isset(
4, &rset))
if(fd_isset(
5, &rset))}}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//接收執行緒:負責接收訊息並顯示
void *recv_thread(
void* arg)
return null;
}int
main(int argc,char *argv)
//設定埠
if(bind(udpfd, (
struct sockaddr*)&addr,
sizeof(addr)) <
0)printf(
"input: \"sayto 192.168.221.x\" to sendmsg to somebody\n");
//建立接收執行緒
pthread_create(&tid, null, recv_thread, (
void*)udpfd);
//建立執行緒
printf(
"\033[32m");
//設定字型顏色
fflush(stdout);
while(
1)else
if(strncmp(buf,
"exit",
4) ==
0)sendto(udpfd, buf, strlen(buf),
0,(struct sockaddr*)&cliaddr,
sizeof(cliaddr));
}return
0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
intmain(int argc,char *argv)
//套接字埠綁字
if(bind(udpfd, (
struct sockaddr*)&saddr,
sizeof(saddr)) !=
0)printf(
"input: \"sayto 192.168.220.x\" to sendmsg to somebody\033[32m\n");
while(
1)else
if(strcmp(buf,
"exit")==
0)sendto(udpfd, buf, strlen(buf),
0,(struct sockaddr*)&caddr,
sizeof(caddr));
}if(fd_isset(udpfd, &rset))
//測試udpfd是否可讀寫}}
return
0;
}
Linux網路程式設計 I O復用之poll函式
目前幾乎在所有的平台上支援,其良好跨平台支援也是它的乙個優點1.每次呼叫 select 都需要把 fd 集合從使用者態拷貝到核心態,這個開銷在 fd 很多時會很大,同時每次呼叫 select 都需要在核心遍歷傳遞進來的所有 fd,這個開銷在 fd 很多時也很大。2.單個程序能夠監視的檔案描述符的數量...
Linux網路程式設計 I O復用之poll函式
小哥整理的不錯,對一些基礎的東西總結的比較全面。一 回顧前面的select select優點 目前幾乎在所有的平台上支援,其良好跨平台支援也是它的乙個優點 select缺點 1.每次呼叫 select 都需要把 fd 集合從使用者態拷貝到核心態,這個開銷在 fd 很多時會很大,同時每次呼叫 sele...
Linux程式設計 IO復用之select詳解
io復用技術使得程式能夠同時監聽多個檔案描述符,這對提高程式的效能至關重要。linux下實現io復用的系統呼叫主要有select poll和epoll,本文主要介紹select,後兩個將在後續文章介紹。盡量使select講解的簡單易懂,便於自己日後複習和有需要的新手朋友。select系統呼叫的主要用...