IO多路轉接
@(Linux)
1.基本概念
適合場景
多用於有大量鏈接,但同一時間活躍量較小
2.select
2.1基本流程
- IO多路轉接的第一種模型,服務器端能夠同時監控多個客戶端的套接字,當有事件發生時,進行相應的操作
- 事件發生:創建新鏈接,讀操作,寫操作,異常處理
- 文件描述符數組:用戶自定義,用於存放套字
- 內核位圖:三種文件描述符集合,系統等待直到有文件描述符狀態改變
2.2函數原語
#include
2.3優缺點
- 優點
- 可以跨平臺
- 缺點
- 描述符有上限 集合中有1024位
- 數據每次都從用戶態拷貝到內核態,自定義數組->集合
- 輪詢遍歷數組,所以描述越多,效率越低
- 重新添加,每次有事件就緒時,監控的文件描述符狀態改變,數組重新添加到集合
- 編碼複雜度較高
3.poll
3.1基本流程
pollfd結構體,用於記錄世界
3.2函數原語
struct pollfd {
int fd; //文件描述符
short events; //監控的集合
short revents; //返回的集合
}
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
fds 可以表示結構體列表,多個結構體
3.3優缺點
- 優點
- 在資源足夠下,描述符無上限
- 編碼複雜度較低
- 缺點
- 態拷貝
- 輪詢遍歷 描述符增加性能降低
- 不可跨平臺
4.epoll
4.1基本流程
建立一個文件描述符集合(監控隊列),在內核態有一個就緒隊列,有事件就緒時加入到就緒隊列
struct epoll_event 事件結構體
fd/ptr
event_poll 紅黑樹–監控隊列,雙向鏈表–就緒列
事件觸發回調—事件觸發,回調函數知道是什麼事件,紅黑樹搜索找到事件,插入雙向鏈表;用戶自定義數組,從鏈表中拷貝,操作
4.2函數原語
epoll_create
epoll_ctl(EPOLL_CTL_ADD) //添加到監控隊列
epoll_wait()
int nfds epoll_wait(struct epoll_event[]) 等待監控, 就緒添加到自定義數組epoll_event
- LT模式 水平觸發 :只要新事件滿足就緒條件就會一直返回通知我們;一共10字節,每次接受2字節,通知5次
- ET模式 邊緣觸發 :只有每次新事件就緒的時候纔會返回給我們通知;一共10字節,每次接受2字節,直到把緩存區數據讀完,最後通知1次;若緩存區已讀完,但對端的寫端沒有關閉,所以會一直阻塞;
- 一次將所有數據讀取出來,否則不會再次提醒,直到下次新數據到了,才提醒;有可能造成recv阻塞,因此需要socket設置爲非阻塞;
- 驚羣效應: 多服務器,負載均衡
4.3優缺點
- 優點
- 描述符無上限
- 事件回調,不會隨着描述符的增加,性能下降;
- 每個事件只需添加到內核態一次,不需要重複添加,效率高
- 編碼難道較小
- 就緒事件直接交付發我們,直接遍歷,不用多餘的遍歷;
- 缺點
- 不可跨平臺