目錄
- IO多路復用技術
- select:
- poll:
- epoll(Linux特有):
- epoll select poll的區別
- epoll是同步還是異步
- epoll詳解
IO多路復用技術
- 通信雙方都有一個socket,以一個文件描述符的形式存在,那這個fd也對應了內核當中的一塊緩存區,緩沖區里有讀緩沖區和寫緩沖區,一端寫另一端讀,IO也就是指這樣對緩沖區的操作。多路復用能夠讓程序同時監聽多個文件描述符。
I/O多路復用技術是一種允許單個進程或線程同時監視多個輸入/輸出(I/O)通道的技術,如網絡連接、文件描述符等。當某個I/O通道有數據可讀或可寫時,操作系統通知應用程序進行相應的操作。這種技術可以提高應用程序的效率和性能,特別是在處理大量并發I/O操作時。以下是幾種常見的I/O多路復用技術:
select:
select是最早的I/O多路復用技術之一。它允許程序指定一組文件描述符,然后查詢這些描述符中哪些已經準備好進行讀取或寫入操作。
poll:
poll與select類似,但它使用不同的數據結構(pollfd結構體數組),并且沒有select中的文件描述符數量限制。
epoll(Linux特有):
epoll是Linux下的一種高效的I/O多路復用技術。它使用一組系統調用(epoll_create、epoll_ctl、epoll_wait)來管理事件和通知機制。epoll使用紅黑樹和事件列表來提高性能,特別是對于大量并發連接。
epoll select poll的區別
select/poll/epoll 都是內核提供給用戶態的多路復用系統調用
- select和poll要檢測的文件描述符集合是在用戶態下創建的,每次調用都需要從用戶態拷貝到內核中。而epoll從創建開始就是在內核空間創建的。
- 判斷是否有文件描述符就緒,select和poll需要遍歷整個文件描述符的集合,遍歷的時間復雜度都是O(n)。而epoll利用了內核的事件驅動機制,只有當文件描述符就緒時才會返回,在硬件的支持下是O(1)的時間復雜度。
- select和poll都只能工作在相對低效的LT模式下,而epoll同時支持LT和ET模式。
- 水平觸發:當文件描述符就緒時,它們會一直通知應用程序直到應用程序處理完該事件
- 邊緣觸發:它只會通知應用程序一次,所以我們一般會循環的從文件描述符中讀寫數據,一次性盡可能多的讀取數據。
- 一般來說,邊緣觸發的效率比水平觸發的效率要高,因為邊緣觸發可以減少系統調用次數,減少開銷的。
- 當監測的fd數量較小,建議使用select和poll;當監聽的fd數量較多,使用epoll會明顯提升性能。
- epoll 在內核里使用「紅黑樹」來關注進程所有待檢測的 Socket
epoll是同步還是異步
epoll 通常被認為是一種介于傳統同步 I/O 和完全異步 I/O 之間的機制。
同步的:epoll 通過 epoll_wait() 系統調用來通知應用程序哪些文件描述符已經準備就緒,應用程序在接收到通知后就要自己去執行實際的 I/O 操作。這種模式更接近于同步 I/O。
異步的:epoll 允許應用程序先注冊對特定的 I/O 事件,當這些事件發生之后操作系統會自動通知應用程序,這是異步 I/O 的一個關鍵特征。
所以總體而言它是同步的,但又提供了一種接近異步 I/O 的編程模型。
epoll詳解
epoll 是 Linux 內核提供的一種高效的 I/O 多路復用技術,用于監控大量文件描述符(file descriptors)的 I/O 事件。與傳統的 select 和 poll 相比,epoll 在處理大量并發連接時具有顯著的性能優勢。以下是 epoll 的一些關鍵特性和概念:
數據結構:
epoll 使用紅黑樹來組織和管理文件描述符,這使得查找、添加和刪除操作都非常高效。
系統調用:
epoll 提供了三個主要的系統調用:
epoll_create:創建一個新的 epoll 實例。
epoll_ctl:用于添加(EPOLL_CTL_ADD)、修改(EPOLL_CTL_MOD)或刪除(EPOLL_CTL_DEL)感興趣的文件描述符。
epoll_wait:等待 I/O 事件的發生,并返回就緒的文件描述符列表。
事件類型:
epoll 支持多種類型的事件,包括讀(EPOLLIN)、寫(EPOLLOUT)、錯誤(EPOLLERR)等。
事件觸發模式:
epoll 支持兩種觸發模式:
邊緣觸發(Edge Triggered,ET):只有狀態發生變化時才通知應用程序。
水平觸發(Level Triggered,LT):只要條件滿足,就會不斷通知應用程序。
性能優勢:
與 select 和 poll 不同,epoll 不需要在每次調用時傳遞所有文件描述符的集合,內核維護了文件描述符的狀態,這大大減少了數據復制的開銷。
就緒列表:
當 epoll_wait 被調用時,內核會將準備好的文件描述符添加到就緒列表中,應用程序可以直接從這個列表中讀取事件,而不需要輪詢。
可擴展性:
epoll 可以高效地處理成千上萬的并發連接,這使得它非常適合用于高性能的服務器應用程序。
內存使用:
盡管 epoll 在性能上優于 select 和 poll,但它可能會使用更多的內存,特別是當監控大量文件描述符時。
編程復雜性:
使用 epoll 編程可能比 select 和 poll 更復雜,需要正確地管理文件描述符的注冊、注銷和事件處理。
epoll 的高效性能使其成為 Linux 下開發高性能網絡應用程序的首選 I/O 多路復用技術之一。然而,開發者需要仔細設計程序,以充分利用 epoll 的優勢,同時避免潛在的編程陷阱。