Linux網路程式設計 I O復用之select詳解

2021-08-21 09:13:15 字數 3772 閱讀 3640

解決程序或執行緒阻塞到某個 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系統呼叫的主要用...