寫tcp併發伺服器的時候,併發的實現方式:
第一種: 阻塞等待
來了乙個客戶端就建立乙個程序或執行緒去伺服器,但是建立的執行緒或程序大多數時間都是處於休眠狀態,所以這種併發的方式比較浪費資源
缺點: 浪費資源(記憶體)
第二種:非阻塞忙輪詢
accept和read都不帶阻塞,程序在不停的輪詢,如果客戶端沒有發來訊息,也沒有新的客戶端請求連線,這個時候程式在做無用功,浪費cpu的資源
第三種: 多路io轉接(多路io復用)
epoll是多路io轉接技術的一種,可以解決select的缺點
epoll沒有檔案描述符的限制
epoll每次重新監聽不需要將檔案描述符從使用者態拷貝至核心態
epoll返回的是已經變化的檔案描述符,不需要在對這顆樹遍歷了
大量併發少了活躍效率高
epoll的工作流程3步:
1建立樹
#include
int epoll_create(int size);
引數: size > 0即可(樹上的 節點最大值,>0自動適配)
返回值: 樹的控制代碼
2將lfd上樹
#include
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能: 操作樹上的節點 -節點上樹 節點下樹 修改節點
引數:epfd: 樹的控制代碼
op:epoll_ctl_add: 上樹
epoll_ctl_del : 下樹
epoll_ctl_mod: 修改
fd: 修改的檔案描述符
event: 節點的位址
返回值:成功返回0 失敗返回-1
typedef union epoll_data epoll_data_t;
struct epoll_event ;
3監聽
#include
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
功能: 迴圈監聽樹上的節點變化
引數:epfd: 樹的控制代碼
events: struct epoll_event陣列的首元素位址,陣列用來接收epoll_wait返回的節點
maxevents:events指向陣列的元素個數
timeout:
-1 永久等待
0 : 不等待
0 : 限時等待返回值: 返回變化的檔案描述符個數
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...
I O多路轉接(select
一.基本概念 二.函式原型 includeint select int nfds,fd set readfds,fd set writefds,fd set exceptions,struct timeval timeout fd set 介面 void fd clr int fd,fd set s...