背景開發,網絡互動是必須的,而epoll基本絕大多數網絡架構的必備武器,本文對epoll進行詳細的介紹,包括epoll的作用,優點,接口,實作原理等。
一. epoll是什麼
epoll是一種IO多路轉接技術,在LINUX網絡程式設計中,經常用來做事件觸發,即當有特定事件到來時,能夠檢測到,而不必阻塞進行監聽。
epoll有兩種工作方式,ET-水準觸發 和 LT-邊緣觸發(預設工作方式),主要的差別是:
LT,核心通知你fd是否就緒,如果沒有處理,則會持續通知。而ET,核心隻通知一次。
二. epoll的優點
與select相比,epoll有以下優點:
2.1. 支援程序打開大量數目的socket描述符,select支援的程序描述符由FD_SETSIZE設定,預設值為
1024,而epoll不受這個限制。
2.2. epoll的效率,不随監聽的socket數目增加而線性下降。
select采用輪詢的方式,對socket集合的描述符表進行掃描,如果socket數量過大,并且大多數
socket屬于idle狀态,select的掃描就做了很多無用功。
epoll隻會對活躍的socket進行操作,是以,在socket數量比較大,而絕大多數socket屬于idle
狀态時,epoll的效率會遠勝于select。如果絕大多數socket是活躍的,由于epoll_ctl的影響,
epoll的效率會稍微比select差。
3.3. 使用mmap加速核心與使用者空間的傳遞,關于mmap,找個時間做個詳細的介紹。
三. epoll的接口
epoll主要有三個接口
3.1 int epoll_create( int size )
建立一個epoll的句柄,size表示監聽的數目一共有多大,我們現網的伺服器,每個程序是設定
12W。
3.2 int epoll_ctl( int epfd, int op, int fd, struct epoll_event* event )
事件注冊函數,epfd是epoll_create傳回的句柄,op是表示做什麼動作,用三個宏表示:
EPOLL_CTL_ADD:注冊新的fd到epfd中;
EPOLL_CTL_MOD:修改已經注冊的fd的監聽事件;
EPOLL_CTL_DEL:從epfd中删除一個fd;
fd表示要監聽的描述符,event表示核心要監聽什麼事,由以下幾個宏表示:
EPOLLIN :表示對應的檔案描述符可以讀(包括對端SOCKET正常關閉);
EPOLLOUT:表示對應的檔案描述符可以寫;
EPOLLPRI:表示對應的檔案描述符有緊急的資料可讀;
EPOLLERR:表示對應的檔案描述符發生錯誤;
EPOLLHUP:表示對應的檔案描述符被挂斷;
EPOLLET: 将EPOLL設為邊緣觸發(Edge Triggered)模式,這是相對于水準觸發(Level Triggered)來說的。
EPOLLONESHOT:隻監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把
這個socket加入到EPOLL隊列裡
3.3 int epoll_wait( int epfd, struct epoll_event* events, int maxevents, int time_out )
等待事件的發生。events,存儲epoll_wait操作完成後,存儲的事件。maxevents表示目前要監聽的
所有socket句柄數。time_out為逾時時間。傳回值表示需要處理的事件數目,0表示逾時。
四. epoll的實作原理
epoll_create
在epoll檔案系統建立了個file節點,并開辟epoll自己的核心高速cache區,建立紅黑樹,配置設定
好想要的size的記憶體對象,建立一個list連結清單,用于存儲準備就緒的事件。
epoll_ctl
把要監聽的socket放到對應的紅黑樹上,給核心中斷處理程式注冊一個回調函數,通知核心,如果
這個句柄的資料到了,就把它放到就緒清單。
epoll_wait
觀察就緒清單裡面有沒有資料,并進行提取和清空就緒清單,非常高效。
LT和ET實作的差別?
由epoll_wait進行實作,如果是LT模式,它發現soket上還有未處理的事件,則在清理就緒清單