Linux I O多路轉接select

2021-08-02 04:46:09 字數 2857 閱讀 7899

系統提供select函式來實現多路復用輸入/輸出模型,那為什麼提供select函式?首先要知道乙個概念,一次i/o分兩個部分(①等待資料就緒 ②進行i/o),減少等待資料的的比重,增加i/o的比重就可以達到高效伺服器的目的。

select工作原理就是減少等的比重,同時監控多個檔案描述符(或者說檔案控制代碼),一旦其中某乙個進入就緒狀態,就進行i/o操作。監控多個檔案控制代碼可以達到提高就緒狀態出現的概率,就可以使cpu在大多數時間下都處於忙碌狀態,大大提高cpu的效能。達到高效伺服器的目的。

select系統呼叫是用來讓我們的程式監視多個檔案控制代碼的狀態變化的。程式會停在select這⾥裡等待,直到被監視的檔案控制代碼有乙個或多個發⽣生了狀態改變。

(1)select函式引數

下⾯面的巨集提供了處理這三種描述片語的⽅方式:

fd_clr(inr fd,fd_set* set);用來清除描述片語set中相關fd 的位

fd_isset(int fd,fd_set *set);用來測試描述片語set中相關fd 的位是否為真

fd_set(int fd,fd_set*set);用來設定描述片語set中相關fd的位

fd_zero(fd_set *set);用來清除描述片語set的全部位

(2)函式返回值:

執行成功則返回.檔案描述詞狀態已改變的個數

如果返回0代表在描述詞狀態改變前已超過timeout時間,沒有返回;

當有錯誤發生時則返回-1,錯誤原因存於errno,

可監控的⽂檔案描述符個數取決與sizeof(fd_set)的值。我這邊服務 器上sizeof(fd_set)=512,每bit表⽰示⼀乙個⽂檔案描述符,則我伺服器上⽀支援的最⼤大⽂檔案描述符是512*8=4096。

將fd加入select監控集的同時,還要再使用乙個資料結構array儲存放到select監控集中的fd,一是用於再select 返回後,array作為源資料和fd_set進行fd_isset判斷。二是select返回後會把以前加入的但並無事件發生的fd清空,則每次開始 select前都要重新從array取得fd逐一加入(fd_zero最先),掃瞄array的同時取得fd最大值maxfd,用於select的第乙個 引數。

可見select模型必須在select前迴圈array(加fd,取maxfd),select返回後迴圈array(fd_isset判斷是否有時間發生)。

每次進行select都要把檔案描述符集fd由使用者態拷貝到核心態,這樣的開銷會很大。

實現select伺服器,內部要不斷對檔案描述符集fd進行迴圈遍歷,當fd很多時,開銷也很大。

select能監控檔案描述符的數量有限,一般為1024。(sizeof(fd_set) * 8 = 1024(fd_set內部是以位圖表示檔案描述符))

#include

#include

#include

#include

#include

#include

#include

#include

#include

int array_fds[1024];

int startup(char* ip, short port)

int opt = 1;

setsockopt(sock,sol_socket,so_reuseaddr,&opt,sizeof(opt));

struct sockaddr_in local;

local.sin_family = af_inet;

local.sin_port = htons(port);

local.sin_addr.s_addr = inet_addr(ip);

//bind

if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)

//listen

if(listen(sock,10) < 0)

return sock;

}int main(int argc,char* argv)

int listen_sock = startup(argv[1],atoi(argv[2]));

int maxfds = 0;//select第乙個引數

fd_set rfds;

int array_size = sizeof(array_fds)/sizeof(array_fds[0]);

array_fds[0] = listen_sock;

//初始化array_fds

int i = 1;

for(;i < array_size;++i)

while(1)

;//非阻塞式等待,null為阻塞式的等待

fd_zero(&rfds);

maxfds = -1;

for(i = 0; i < array_size;++i)

}switch(select(maxfds+1,&rfds,null,null,/*&timeout*/null ))

else

}if(k == array_size)//表示沒有可用的檔案介面

close(new_fd);}}

else

if(j != 0 && fd_isset(array_fds[j],&rfds))

else

if(s == 0)

else }}

}break;}}

return

0;}

Linux I O多路轉接poll

不同與select使用三個點陣圖來表示三個fdset的方式,poll使用 乙個 pollfd的指標實現。poll函式和select函式的任務相似 等待一組檔案描述符來準備執行i 0。引數 1 第乙個引數 fds struct pollfd 2 第二個引數 nfds nfds用來表示要監視檔案描述符的...

Linux IO多路復用 多路轉接

io多路復用 多路轉接 在沒有io多路復用技術前,程序在同一時間只能監控乙個io狀態 乙個檔案描述符的狀態 例如a和b兩個檔案在操作,定的順序是a前b後,那麼在a阻塞過程中 b在後面也是不能被操作的,這樣會造成資源浪費 響應緩慢。io多路復用 同時監控多個io檔案描述符狀態,如果沒有準備好的描述符 ...

Linux I O多路轉接 poll模型

1.poll模型屬於i o多路轉接模型,是對select模型的一種優化 int poll struct pollfd fds,nfd t nfds,int timeout 2.poll的優點 poll使用陣列儲存檔案描述符,所以能描述的檔案描述個數在理論上沒有上限 poll將輸入輸出型引數進行了分離...