成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

圖解 | Epoll怎么實現的

系統
epoll 可以說是編寫高性能服務端程序必不可少的技術,在介紹 epoll 之前,我們先來了解一下 多路復用I/O 吧。

 [[394368]]

epoll 可以說是編寫高性能服務端程序必不可少的技術,在介紹 epoll 之前,我們先來了解一下 多路復用I/O 吧。

多路復用I/O

多路復用I/O:是指內核負責監聽多個 I/O 流,當任何一個 I/O 流處于就緒狀態(可讀或可寫)時都會通知進程,以便可以處理該 I/O 流上的數據。如 圖1 所示:

如 圖1 所示,內核負責監聽多個 I/O 流,當某些 I/O 流變為就緒狀態,內核會把這些 I/O 流添加到就緒隊列中,然后通知進程處理就緒隊列中的 I/O 流。

與傳統的阻塞型 I/O 相比,多路復用 I/O 的優點是可以同時監聽多個 I/O 流,并且會把就緒的 I/O 流告知進程。

epoll原理

介紹完多路復用 I/O,接下來開始介紹我們的主角:epoll。

在 Linux 系統中,有多種多路復用 I/O 的實現,比如 select 和 poll 等。而 epoll 也是多路復用 I/O 一種實現,與 select 和 poll 相比,epoll 在性能上有較大的提升。

紅黑樹

epoll 內部使用紅黑樹來保存所有監聽的 socket,紅黑樹是一種平衡二叉樹,添加和查找元素的時間復雜度為 O(log n),其結構如 圖2 所示:

epoll 通過 socket 句柄來作為 key,把 socket 保存在紅黑樹中。如 圖2 所示,每個節點中的數字代表著 socket 句柄。

把監聽的 socket 保存在紅黑樹中的目的是,為了在修改監聽 socket 的讀寫事件時,能夠通過 socket 句柄快速找到對應的 socket 對象。

就緒隊列

另外,epoll 還維護著一個就緒隊列,當 epoll 監聽的 socket 狀態發生改變(變為可讀或可寫)時,就會把就緒的 socket 添加到就緒隊列中。如 圖3 所示:

當 socket 從網絡中獲取到數據后,會發生通知給 epoll,epoll 會將當前 socket 添加到就緒隊列中,并且喚醒等待中的進程(也就是調用 epoll_wait 的進程)。

當 socket 狀態發生變化時,會調用 ep_poll_callback 函數來通知 epoll,我們來看看這個函數的處理過程:

  1. static int ep_poll_callback(wait_queue_t *wait, unsigned mode,  
  2.                             int sync, void *key
  3.     ... 
  4.     struct epitem *epi = ep_item_from_wait(wait); 
  5.     struct eventpoll *ep = epi->ep; 
  6.     ... 
  7.     // 1) 把 socket 添加到就緒隊列中 
  8.     list_add_tail(&epi->rdllink, &ep->rdllist); 
  9.  
  10. is_linked: 
  11.     // 2) 喚醒調用 epoll_wait() 而被阻塞的進程 
  12.     if (waitqueue_active(&ep->wq)) 
  13.         wake_up_locked(&ep->wq); 
  14.     ... 
  15.     return 1; 

ep_poll_callback 函數的意圖很清晰,主要完成兩個工作:

  • 把就緒的 socket 添加到就緒隊列中。
  • 喚醒調用 epoll_wait 函數而被阻塞的進程。

當進程被喚醒后,就會從就緒隊列中,把就緒的 socket 復制到用戶提供的數組中。如 圖4 所示:

如 圖4 所示,在調用 epoll_wait 時需要提供一個 events 數組來存儲就緒的 socket。當 epoll_wait 返回后,用戶就可以從events 數組中獲取到就緒的 socket,并可對其進行讀寫操作。

總結

本文主要通過圖解的方式大概介紹了 epoll 的原理,但很多實現的細節只能通過閱讀源碼來了解。如果對 epoll 的實現有興趣,可以參考《epoll 如何工作的》這篇文章。

 

責任編輯:武曉燕 來源: Linux內核那些事
相關推薦

2021-06-26 07:04:24

Epoll服務器機制

2022-06-07 10:40:56

流程數據庫MySQL

2023-01-04 13:43:24

讀寫鎖AQS共享模式

2021-07-07 10:05:38

進程CPULinux

2021-03-30 09:45:11

悲觀鎖樂觀鎖Optimistic

2021-09-30 10:45:33

Linux進程通信

2020-12-09 10:29:53

SSH加密數據安全

2022-06-20 08:03:17

KafkaJava NIO

2015-10-21 10:24:05

TCPIP網絡協議

2023-03-11 11:19:07

loopbackSocket

2023-01-27 18:08:35

eBPF云原生

2011-04-01 13:32:27

路由路由器

2009-12-31 09:12:30

華為ADSL設置

2011-04-01 13:55:58

路由路由器路由表

2021-07-14 09:48:15

Linux源碼Epoll

2011-04-01 14:15:37

路由篩選器

2023-05-29 08:31:48

Redis散列表

2020-04-02 09:58:26

Kubernetes容器開發

2022-03-07 09:42:21

Go快速排序

2021-05-11 08:22:32

Epoll 監聽I
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩在线视频精品 | av男人天堂影院 | 夜夜艹 | 伊人亚洲 | 成人免费毛片在线观看 | 成年人在线观看视频 | 99精品国自产在线 | 黄a免费看 | 亚洲精品国产区 | 91久久精品一区二区三区 | 日本精品一区二区在线观看 | 久久国产一区 | 国产精品嫩草影院精东 | 亚洲在线免费 | 免费av一区二区三区 | 毛片一级黄色 | 日本不卡高清视频 | 婷婷国产一区二区三区 | 亚洲福利 | 亚洲激情网站 | 久久网日本 | 日韩av在线一区 | 日韩av一二三区 | 免费观看a级毛片在线播放 黄网站免费入口 | 中文字幕日韩一区二区 | 亚洲啪啪 | 国产福利观看 | 一区二区免费看 | 成人精品福利 | 免费一看一级毛片 | a毛片 | 欧美日一区二区 | 久久国产精品一区二区三区 | 国产欧美二区 | 成人一区二区在线 | 91久久国产综合久久 | 国产一区二区黑人欧美xxxx | 国产视频二区在线观看 | 久久成人国产精品 | 欧美1—12sexvideos | 99精品一区二区三区 |