多路轉接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...