多路复用IO模型中的select和epoll
多路復用IO模型中的select和epoll
一,前提知識——文件描述符fd
1、文件描述符簡介
首先從文件描述符開始講起。因為,對于內核而言,所有打開的文件都是通過文件描述符引用的。那么文件描述符到底是什么?
文件描述符(file descriptor)通常是一個小的非負整數,內核用以標識一個特定進程正在訪問的文件。當打開一個現有文件或創建一個新文件時,內核向進程返回一個文件描述符。當讀、寫一個文件時,使用 open 或 create 返回的文件描述符標識該文件,將其作為參數傳送給 read 或 write。
我的理解,文件描述符就是內核用來標識某進程正在訪問文件的一個標志。
二,概念介紹
select,poll,epoll都是IO多路復用的機制。I/O多路復用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。但select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而異步I/O則無需自己負責進行讀寫,異步I/O的實現會負責把數據從內核拷貝到用戶空間。
三,select流程
1, 拿到所有需要輪詢的文件描述符fd,從用戶空間拷貝到內核空間。
2, 注冊回調函數。
3, 遍歷所有的fd。
4, 調用poll,返回是否讀寫就緒的mask掩碼。
5,遍歷結束,進入睡眠(超時重新喚起遍歷或者回調epoll喚起)。
6,繼續遍歷,從3開始。
7,結束,將所有fd重新拷貝回用戶空間。
select的幾大缺點:
(1)每次調用select,都需要把fd集合從用戶態拷貝到內核態,這個開銷在fd很多時會很大
(2)同時每次調用select都需要在內核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大
(3)select支持的文件描述符數量太小了,默認是1024
四,epoll的改進
首先在select里需要在每次調用select都會拷貝fd。epoll只拷貝一次。
原因是:
select和poll都只提供了一個函數——select或者poll函數。而epoll提供了三個函數,epoll_create, epoll_ctl 和epoll_wait,epoll_create是創建一個epoll句柄;epoll_ctl是注冊要監聽的事件類型;epoll_wait則是等待事件的產生,epoll的解決方案在epoll_ctl函數中。每次注冊新的事件到epoll句柄中時(在epoll_ctl中指定EPOLL_CTL_ADD),會把所有的fd拷貝進內核,而不是在epoll_wait的時候重復拷貝。epoll保證了每個fd在整個過程中只會拷貝一次
而且epoll的回調函數不是返回是否讀寫就緒,而是直接將就緒的fd拷貝加入一個就緒鏈表。所以epoll的遍歷喚醒時不用像select一樣再遍歷一遍fd集合,而只需要看一下就緒鏈表是否為空,如果不為空進行讀寫即可。
還有select有fd的支持數量只有1024,而epoll無限制,只被系統內存限制,測試中1G內存可以支持10W左右。cat /proc/sys/fs/file-max可以查看。
總結
以上是生活随笔為你收集整理的多路复用IO模型中的select和epoll的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5种网络IO模型介绍
- 下一篇: RocketMQ 核心