多路轉接IO select的基本使用

2021-10-14 01:47:55 字數 2467 閱讀 3872

多路轉接io,通常也稱為多路復用io。

作用:io多路轉接可以實現對大量描述符的監控,監控的事件可以為可讀、可寫、異常。

當我們使用多路轉接的時候,若某時刻該介面發現了監控下的某個描述符就緒,就會通知程序,進而針對該描述符進行操作,而其它未就緒的描述符則繼續監控。

優點:避免了當其它檔案描述符未就緒時,程序陷入阻塞的情況

介面函式
介面函式:

int select (int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout);

函式引數:

nfds:取值通常為最大檔案的描述符數值+1,目的是為了提高select的監控效率

fd_set:它的本質是乙個結構體,但該結構體內只有乙個元素即乙個陣列fds_bits,該陣列被當作位圖使用,大小為16 * 64=1024,也符合檔案描述fd在核心的本質

提供了四個操作該位圖的函式:

void fd_crl(int fd,fd_set* set) // 從事件集合當中刪除某乙個檔案描述符

int fd_isset(int fd,fd_set* set)//判斷fd是否在set中,0表示沒有,非0則在

void fd_set(int fd,fd_set* set)//設定fd,到集合set中

void fd_zero(fd_set* set)//清空

writefds和exceptfds通常給null

timeout:超時時間

struct timeval

timeval== null :阻塞監控

timeval== 0 (tv_sec0 tv_usec 0):非阻塞監控

timecal > 0 :帶有超時時間的監控

使用技巧

可以直接將select的所有操作封裝為乙個類,類成員函式為乙個fd_set* 的點陣圖和當前最大的檔案描述符

當需要監控的時候將對應檔案描述符加入,呼叫監控介面,當返回值大於0即有描述符就緒時,將對應描述符通過最大描述符提取出來,隨之處理。

特別注意的點:select介面會將沒有就緒的檔案描述符從集合中去除掉,因此在使用的時候通常引入乙個中間變數,將改變了傳入

select的乙個簡單例子

實現的是乙個tcp通訊,在服務端採用select進行監控,解決了多個連線時未響應連線導致阻塞的問題。

select.hpp

#pragma once

#include

#include

#include

#include

#include

"tcpsvr.hpp"

class

selectsvr

~selectsvr()

void

addfd

(int fd)

}void

deletefd

(int fd)

}bool

selectwait

(std::vector

* vec)

else

if(ret ==0)

//正常情況

for(

int i =

0; i < max_fd_; i++)}

return

true;}

private

:int max_fd_;

fd_set readfds_;

};

server.cpp

#include

"selectsvr.hpp"

#define check_ret(p) if(p != true)

intmain()

for(size_t i =

0; i < vec.

size()

; i++

)//3.連線上有資料

else

printf

("client send data is [%s]\n"

, data.

c_str()

);}}

}return0;

}

select效能分析

優點:select遵循posix標準,可以跨平台移植

select的超時時間可以精確到微秒

缺點:select是輪詢遍歷的,監控效率隨著檔案描述符的增多而下降select所能監控的檔案描述符有上限,即1024個

select在返回檔案描述符的時候,會將未就緒的檔案描述符移除掉,導致二次監控的時候,需要再次新增

select無法直接告訴使用者哪個檔案描述符就緒了,程式設計師必須從返回的事件集合中自行判斷

多路復用I O select

include int select int maxfdp1,fd set restrict readfds,fd set restrict writefds,fd set restrict exceptfds,struct timeval restrict tvptr 返回值 準備就緒的描述符數目...

I O多路轉接

對於多個非阻塞i o,怎麼知道i o何時已經處於可讀或可寫狀態?如果採用迴圈一直呼叫write read,直到返回成功,這樣的方式成為輪詢 polling 大多數時間i o沒有處於就緒狀態,因此這樣的輪詢十分浪費cpu。一種比較好的技術是使用i o多路轉接,也叫做i o多路復用。其基本思想為 先構造...

I O多路轉接

include include include include include include include include include include include 巨集定義埠號 define portnumber 8000 define max line 80 int main void...