1.文件描述符
linux下的文件描述符是一個用於表述指向文件的引用的抽象化概念(在windows下是HANDLE句柄).
文件描述符在形式上是一個非負整數值.但實際上,他是一個索引值,指向系統內核為每個進程維護的一張記錄表.
在這張記錄表上記錄每個進程打開的文件對應的文件結構體信息.
那么也就是說,文件描述符不存在事件這一說法,文件描述符本身不會產生事件,但文件描述符對應的文件可能會因為modify而產生事件.
這些事件是怎么產生的,由誰產生的,怎樣讓epoll捕捉到此事件.都是系統在對事件進行維護和通知
這是理解epoll的一個重要因素.
2.epoll工作模式
epoll不產生事件,但它監聽並報告事件.
報告的事件類型有:
EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLET | EPOLLONESHOT |
如果監聽的文件描述符對應的文件出現了以上七種事件,就可以被epoll正確的捕捉到.
epoll可以在兩種模式下來捕捉監聽的文件描述符產生的事件.
第一種是:ET模式,也就是Edge Triggered模式,只有文件發生變化的時候才會報告事件,意思是在一段時間內,連續的同樣事件只報告一次,之后即便有相同的事件,也不再向上提交.
第二種是:LT模式,也就是Level Triggered模式,在這種模式下,epoll如實將文件上的事件向上一一傳達,文件上什么時候有事件,有什么事件,epoll就向上傳達什么,直到該事件被操作系統消除.
3.應用方式
目前接觸過的應用中如果使用ET模式,文件描述符必須設為非阻塞模式以避免由於一個文件的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死,比如在對socket鏈接進行事件監聽時,如果收到epoll的通知,那么就代表網絡上有數據到來,然后循環recv,直到返回值小於指定的讀取數據長度,錯誤碼為EAGAIN時,表示鏈接上的數據已經讀取完畢,應該去等待下一次的通知;又比如,在socket的accpet上,一旦收到通知,就不斷地進行accept直到返回值為-1,把accept隊列的所有已經完成建立連接的socket fd拿出來向上遞交.
總結:事件由系統產生,epoll提供了事件通知的兩種方式,文件描述符作為事件附着的抽象標識.