epoll的理論與IO阻塞機制


流?I/O操作? 阻塞?

(1)流

▪ 可以進⾏I/O操作的內核對象

▪ ⽂件、管道、套接字……

▪ 流的⼊⼝:⽂件描述符(fd)

(2)I/O操作

所有對流的讀寫操作,我們都可 以稱之為IO操作。

(3)阻塞

阻塞等待 不占⽤CPU寶貴的時間⽚

⾮阻塞忙輪詢 占⽤CPU,系統資源

在處理意⻅數據的接收場景時, 我們建議優先選擇阻塞等待的⽅ 式, 不浪費性能資源

(4)阻塞等待缺點:

不能夠很好的處理 多個(I/O)請求的問題

同⼀個阻塞,同⼀時刻只能處理⼀個流的阻塞監聽

(5)多路IO復⽤

既能夠阻塞等待,不浪費資源

也能夠同⼀時刻監聽多個IO請求的狀態

解決阻塞死等待的缺點(如何解決⼤量IO請求讀寫的問題)

⽅法⼀ : 阻塞等待+多進程/多線程

需要開辟線程浪費資源

⽅法⼆:⾮阻塞+忙輪詢

while true {
    for i in 流[] {
       if i has 數據 {
         讀 或者 其他處理
      }
   }
}        

CPU在⼤量的做判斷,while和for

cpu的利⽤率不⾼

方法三:多路IO復⽤機制   select(與平台⽆關)

監聽的IO數量有限,默認是1024個

不會精准的告訴開發者,哪些IO是可讀可寫的,需要遍歷

while true {
    select(流[]); //阻塞
     //有消息抵達
    for i in 流[] {
        if i has 數據 {
            讀 或者 其他處理
        }
    }
}                    

方法四:多路IO復⽤機制  epoll(Linux)

通過 /proc/sys/fd/file-max查看)

while true {
    可處理的流[] = epoll_wait(epoll_fd); //阻塞
     //有消息抵達,全部放在 “可處理的流[]”中
    for i in 可處理的流[] {
        讀 或者 其他處理
    }
}    

epoll 的API

(1) 創建EPOLL

int epoll_create(int size);

(2) 控制EPOLL

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

(3) 等待EPOLL

int epoll_wait(int epfd, struct epoll_event *event, int maxevents, int timeout);

(4) 使⽤epoll編程主流程⻣架

觸發模式

⽔平觸發:

⽔平觸發的主要特點是,如果⽤戶在監聽epoll事件,當內核有事件的時候,會拷⻉給⽤戶態事 件,但是如果⽤戶只處理了⼀次,那么剩下沒有處理的會在下⼀次epoll_wait再次返回該事 件。

默認就是⽔平觸發模式

邊緣觸發:

邊緣觸發,相對跟⽔平觸發相反,當內核有事件到達, 只會通知⽤戶⼀次,⾄於⽤戶處理還是不處理, 以后將不會再通知。這樣減少了拷⻉過程,增加了性能,但是相對來說,如果⽤戶⻢⻁忘記處理,將會產 ⽣事件丟的情況。

在給事件進⾏綁定的時候,通過EPOLLET來設置

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM