深入理解epoll

文章目錄

  • 概述
  • 1. epoll_create - 創建一個epoll實例
  • 2. epoll_ctl - 控制epoll實例的事件
    • 結構體介紹
      • events取值:
      • data: 聯合體(共用體):
  • 3. epoll_wait - 等待事件發生
  • 偽代碼
  • 總結

概述

在網絡編程中,高效地處理大量并發連接是一個關鍵問題。而Linux提供的epoll機制成為了解決這個問題的重要工具。epoll是一種I/O事件通知機制,通過三個主要函數,即epoll_create、epoll_ctl和epoll_wait,實現了高性能的事件驅動并發編程。讓我們深入了解這三個函數以及它們的使用方法。

1. epoll_create - 創建一個epoll實例

int epoll_create(int size);

size:創建的紅黑樹的監聽節點數量。(僅供內核參考。)
返回值:指向新創建的紅黑樹的根節點的 fd。
-1:代表錯誤

2. epoll_ctl - 控制epoll實例的事件

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

epfd:epoll_create 函數的返回值。 epfd
op:對該監聽紅黑數所做的操作。
EPOLL_CTL_ADD 添加fd到 監聽紅黑樹
EPOLL_CTL_MOD 修改fd在 監聽紅黑樹上的監聽事件。
EPOLL_CTL_DEL 將一個fd 從監聽紅黑樹上摘下(取消監聽)
fd:待監聽的fd
event: 本質 struct epoll_event 結構體指針
返回值:成功 0; 失敗: -1 errno

結構體介紹

struct epoll_event {__uint32_t events; /* Epoll events */epoll_data_t data; /* User data variable */};typedef union epoll_data {void *ptr;int fd;uint32_t u32;uint64_t u64;} epoll_data_t;

events取值:

EPOLLIN : 表示對應的文件描述符可以讀(包括對端SOCKET正常關閉)
EPOLLOUT: 表示對應的文件描述符可以寫
EPOLLERR: 表示對應的文件描述符發生錯誤
等等(不重要)

data: 聯合體(共用體):

int fd; 對應監聽事件的 fd
void *ptr; 回調函數
uint32_t u32;
uint64_t u64;

3. epoll_wait - 等待事件發生

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

epoll_wait函數用于等待事件發生,當事件發生時將返回就緒的文件描述符以及對應的事件類型。參數包括:

epfd:epoll_create 函數的返回值。 epfd

events:傳出參數,【數組】, 滿足監聽條件的 那些 fd 結構體。

maxevents:上面數組元素的總個數。 eg:struct epoll_event evnets[1024]->1024

timeout:
-1: 阻塞
0: 不阻塞
大于0: 超時時間 (毫秒)
返回值:
大于0: 滿足監聽的 總個數。 可以用作循環上限。
0: 沒有fd滿足監聽事件
-1:失敗。 errno

在這里插入圖片描述

偽代碼

關于代碼實現可以參考:鏈接
epoll實現多路IO轉接思路:

lfd = socket();			監聽連接事件lfd
bind();
listen();int epfd = epoll_create(1024);				epfd, 監聽紅黑樹的樹根。struct epoll_event tep, ep[1024];			tep, 用來設置單個fd屬性, ep 是 epoll_wait() 傳出的滿足監聽事件的數組。tep.events = EPOLLIN;					初始化  lfd的監聽屬性。
tep.data.fd = lfdepoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &tep);		將 lfd 添加到監聽紅黑樹上。while (1) {ret = epoll_wait(epfd, ep,1024-1);			實施監聽for (i = 0; i < ret; i++) {if (ep[i].data.fd == lfd) {				// lfd 滿足讀事件,有新的客戶端發起連接請求cfd = Accept();tep.events = EPOLLIN;				初始化  cfd的監聽屬性。tep.data.fd = cfd;epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &tep);} else {						cfd 們 滿足讀事件, 有客戶端寫數據來。n = read(ep[i].data.fd, buf, sizeof(buf));if ( n == 0) {close(ep[i].data.fd);epoll_ctl(epfd, EPOLL_CTL_DEL, ep[i].data.fd , NULL);	// 將關閉的cfd,從監聽樹上摘下。} else if (n > 0{--write(ep[i].data.fd, buf, n);}}}

總結

通過使用epoll_create、epoll_ctl和epoll_wait這三個主要函數,我們可以充分利用Linux的epoll機制來實現高效的事件驅動并發編程。首先,通過創建epoll實例,我們能夠監控多個文件描述符。然后,使用epoll_ctl函數來添加、修改和刪除需要監控的事件。最后,通過調用epoll_wait函數來等待事件的發生并處理就緒的文件描述符。

這些函數的合理使用可以幫助我們有效地管理大量并發連接,提高系統的性能和響應能力。當然,在實際應用中,我們還需要結合其他的網絡編程知識和技巧,以實現更加穩定和高效的網絡應用程序

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38997.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38997.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38997.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

每天一道leetcode:797. 所有可能的路徑(圖論中等深度優先遍歷)

今日份題目&#xff1a; 給你一個有 n 個節點的 有向無環圖&#xff08;DAG&#xff09;&#xff0c;請你找出所有從節點 0 到節點 n-1 的路徑并輸出&#xff08;不要求按特定順序&#xff09; graph[i] 是一個從節點 i 可以訪問的所有節點的列表&#xff08;即從節點 i 到節…

c++11 explicit關鍵字的作用

explicit 在C中&#xff0c;explicit關鍵字用來修飾類的構造函數&#xff0c;被修飾的構造函數的類&#xff0c;不能發生相應的隱式類型轉換&#xff0c;只能以顯示的方式進行類型轉換。因為無參構造函數和多參構造函數本身就是顯示調用的。再加上explicit關鍵字也沒有什么意義…

?五金件機器視覺定位?并獲取外觀輪廓軟硬件視覺方案

【檢測目的】 五金件機器視覺定位&#xff0c;視覺檢測五金件輪廓并矯正五金件位置進行涂油 【客戶要求】 FOV:540*400mm 【拍攝與處理效圖一】 【拍攝與處理效圖二】 【實驗原理及說明】 【方案評估】 根據目前的圖像和處理結果來看&#xff0c;可以檢測出產品輪廓并進行位置…

HCIP-OpenStack搭建

1、OpenStack概述 OpenStack是一種云操作系統&#xff0c;OpenStack是虛擬機、裸金屬和容器的云基礎架構。可控制整個數據中心的大型計算、存儲和網絡資源池&#xff0c;所有資源都通過具有通用身份驗證機制的API進行管理和配置。管理員也可通過Web界面控制&#xff0c;同時授…

Qt 之 QPushButton,信號與槽機制

文章目錄 前言一、QPushButton二、信號與槽機制總結 前言 一、QPushButton 當我們開發基于Qt框架的圖形用戶界面&#xff08;GUI&#xff09;應用程序時&#xff0c;經常需要在界面上添加按鈕來實現用戶交互。Qt提供了一個名為 QPushButton 的類作為按鈕控件的實現。QPushButt…

基于RoCE的應用程序的MTU注意事項

目錄 基于RoCE的應用程序的MTU注意事項 探測網絡中的MTU設置 概要 原文 MTU測試結果 DOC: CentOS安裝tshark抓包工具 基于RoCE的應用程序的MTU注意事項 原文&#xff1a;https://support.mellanox.com/s/article/MLNX2-117-1682kn InfiniBand協議最大傳輸單元&#xff…

WSL2 Ubuntu子系統安裝OpenCV

文章目錄 前言一、&#xfeff;基本概念二、操作步驟1.下載源碼2.安裝依賴3.運行編譯4.配置路徑 前言 OpenCV用C語言編寫&#xff0c;它的主要接口也是C語言&#xff0c;但是依然保留了大量的C語言接口。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的接口。這些語…

C#委托事件的區別

在C#中&#xff0c;委托&#xff08;delegate&#xff09;和事件&#xff08;event&#xff09;經常一起使用&#xff0c;但它們之間確實有一些基本的區別&#xff1a; 委托&#xff08;Delegate&#xff09;&#xff1a;委托是一個引用類型&#xff0c;它可以引用一個或多個具…

[python] 安裝numpy+scipy+matlotlib+scikit-learn及問題解決

這篇文章主要講述Python如何安裝Numpy、Scipy、Matlotlib、Scikit-learn等庫的過程及遇到的問題解決方法。最近安裝這個真是一把淚啊&#xff0c;各種不兼容問題和報錯&#xff0c;希望文章對你有所幫助吧&#xff01;你可能遇到的問題包括&#xff1a; ImportError: N…

高并發數據抓取實戰:使用HTTP爬蟲ip提升抓取速度

又到每天一期學習爬蟲的時間了&#xff0c;作為一名專業的爬蟲程序員&#xff0c;今天要跟你們分享一個超實用的技巧&#xff0c;就是利用HTTP爬蟲ip來提升高并發數據抓取的速度。聽起來有點高大上&#xff1f;別擔心&#xff0c;我會用通俗易懂的話來和你們說&#xff0c;讓你…

自定義組件引入使用單標簽還是雙標簽好

在許多前端框架和庫中&#xff0c;自定義組件可以使用單標簽或雙標簽進行引入和使用。讓我為您解釋一下這兩種方式的區別和使用場景。 單標簽&#xff08;Self-closing Tag&#xff09;&#xff1a;使用單標簽來引入自定義組件意味著您在組件的使用中只需要一個標簽&#xff0…

自動切換HTTP爬蟲ip助力Python數據采集

在Python的爬蟲世界里&#xff0c;你是否也被網站的IP封鎖問題困擾過&#xff1f;別擔心&#xff0c;我來教你一個終極方案&#xff0c;讓你的爬蟲自動切換爬蟲ip&#xff0c;輕松應對各種封鎖和限制&#xff01;快來跟我學&#xff0c;讓你的Python爬蟲如虎添翼&#xff01; 首…

如何使用mysql命令行導出csv文件?

首先打開ssh&#xff0c;使用命令行登錄mysql mysql -uroot -p123456 其中-u后面的root是用戶名&#xff0c;-p后面的123456是密碼 &#xff0c;替換成自己的賬戶和密碼即可 然后切換到自己需要操作的數據庫&#xff0c;例如test數據庫 use test 接下來執行語句來選擇要導…

服務器托管中1U是什么意思?

U的概念 U是一種表示服務器外部尺寸的單位&#xff0c;是unit的縮略語。 1U4.44514.445cm 2U4.44528.89cm 4U4.445*413.335cm 在托管服務器時&#xff0c;服務商經常說的“1U”是外形滿足EIA&#xff08;美國電子工業協會&#xff09;規格、厚度為4.445cm的產品&#xff0c;設…

uniapp-微信小程序篇

uniapp-微信小程序篇 一、創建項目(以Vue3TS 項目為示例) 可以通過命令行的方式創建也可以通過HBuilderX進行創建&#xff08;通過HBuilderX創建的項目建議選擇最簡單的模板&#xff09;&#xff0c;個人建議使用命令行方式。 (1) 命令行方式&#xff1a; npx degit dcloudio…

ABAP 期初庫存批量導入 demo1

&--------------------------------------------------------------------- *& Report ZMMCP005 &--------------------------------------------------------------------- 作者&#xff1a; Liv完成日期&#xff1a;描述&#xff1a; 期初庫存導入需求簡要說明&…

uni-app 面容、指紋識別插件(uni-face-login)

面容、指紋識別插件(uni-face-login) 介紹 人臉指紋登錄授權&#xff0c;可以使用手機自帶的人臉、指紋進行生物識別&#xff0c;進而判斷是否機主本人&#xff0c;從而進行授權驗證&#xff0c;適配安卓、iOS、鴻蒙設備 猛戳這里去插件市場看看 使用 該插件支持鴻蒙、安卓…

UE4/5C++多線程插件制作(二十一、使用)

目錄 DemoPawn.h DemoPawn.cpp 會出現的bug 插件 相關的插件制作在上一節已經完成了。 具體的使用方式在第0章已經寫了,get之后去綁定即可。 而后筆者做了一個接口,具體的綁定方式也就在這個接口里面。 接下來最重要的是進行使用,對此我做了一個與藍圖相關的接口,里…

TypeScript教程(一)簡介與安裝

一、簡介 TypeScript 是 JavaScript 的一個超集&#xff0c;擴展了JavaScript的語法&#xff0c;因此現有的JavaScript可與TypeScript一起工作無需修改&#xff0c;支持 ECMAScript 6 標準&#xff08;ES6 教程&#xff09;。 語言特性&#xff1a; 1.類型批注和編譯時類型檢…

怎么學習AJAX相關技術? - 易智編譯EaseEditing

學習AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;相關技術可以讓你實現網頁的異步數據交互&#xff0c;提升用戶體驗。以下是一些學習AJAX技術的步驟和資源&#xff1a; HTML、CSS和JavaScript基礎&#xff1a; 首先&#xff0c;確保你已經掌握了基本的HTML…