深度剖析并發I/O模型select、poll、epoll與IOCP核心機制

核心概要selectpollepollIOCP 是四種用于提升服務器并發處理能力的I/O模型或機制。前三者主要屬于I/O多路復用范疇,允許單個進程或線程監視多個I/O流的狀態;而 IOCP 則是一種更為徹底的異步I/O模型

一、引言:為何需要這些技術?

在網絡服務器開發中,一個核心挑戰是如何高效地處理大量并發連接。傳統的阻塞式I/O模型(一個線程處理一個連接,并在I/O操作時阻塞)在并發量高時會導致線程數量激增,帶來巨大的上下文切換開銷和資源消耗。為了解決這一問題,發展出了I/O多路復用和異步I/O技術。

二、I/O多路復用技術:select, poll, epoll

I/O多路復用允許單個進程監視多個文件描述符(FD),一旦某個或某些FD就緒(例如,可讀或可寫),便通知應用程序進行相應的I/O操作。應用程序本身在調用這些多路復用函數時可能會阻塞,但一旦收到通知,后續的I/O操作(如read, write)通常可以非阻塞地執行,或者至少是已知的可操作狀態。

1. select

一句話介紹select 是一種傳統的I/O多路復用機制,它允許程序監視一組文件描述符,等待一個或多個描述符變為就緒狀態。

工作機制

  • 應用程序通過 fd_set 數據結構向內核注冊需要監視的讀、寫和異常文件描述符集合。

  • 調用 select 函數,該調用會阻塞,直到有文件描述符就緒或超時。

  • select 返回后,內核會修改傳入的 fd_set 來指示哪些文件描述符已就緒。

  • 應用程序需要遍歷整個 fd_set 來找出具體就緒的文件描述符,并對其進行操作。

主要特點

  • 跨平臺性:作為早期標準,select 具有良好的跨平臺兼容性。

  • 文件描述符數量限制:受 FD_SETSIZE 宏的限制(通常為1024或2048),能夠監視的文件描述符數量有限。

  • 性能開銷:

    • 每次調用都需要將 fd_set 在用戶空間和內核空間之間完整拷貝。

    • 內核在檢查時需要遍歷所有被監視的FD。

    • 應用程序在返回后也需要遍歷 fd_set 以確定哪些FD就緒。

舉例:想象一位老派的郵局分揀員。每次來一批信件(FD集合),他都要把所有信箱(所有被監視的FD)檢查一遍,看看哪些信箱里有新信(FD就緒)。即使只有少數信箱有信,他也得全部看一遍。而且他能管理的信箱總數也是固定的

2. poll

一句話介紹pollselect 的一種改進,它解決了文件描述符數量的限制,并使用不同的數據結構來管理監視的描述符。

工作機制

  • 應用程序使用一個 pollfd 結構體數組來指定要監視的文件描述符及其關心的事件(如 POLLIN 表示可讀,POLLOUT 表示可寫)。

  • 調用 poll 函數,該調用會阻塞,直到有描述符就緒或超時。

  • poll 返回后,內核會在 pollfd 結構體中的 revents 字段中標示出哪些文件描述符發生了哪些事件。

  • 應用程序需要遍歷這個 pollfd 數組來找出就緒的描述符。

主要特點

  • 無文件描述符數量硬性限制:監視的FD數量僅受系統資源限制。

  • 數據結構改進:使用 pollfd 結構體,每個結構體對應一個FD,避免了 selectfd_set 的固定大小問題。

  • 性能開銷依然存在:

    • 每次調用仍需將 pollfd 數組在用戶空間和內核空間之間拷貝。

    • 內核和應用程序仍需遍歷所有被監視的FD(即使只有少數就緒)。

3. epoll (Linux Specific)

一句話介紹epoll 是 Linux 內核提供的高效I/O多路復用機制,它顯著改善了處理大量并發連接時的性能。

工作機制

epoll 的使用分為三個主要步驟:

  1. epoll_create / epoll_create1:在內核中創建一個 epoll 實例,返回一個代表該實例的文件描述符。

  2. epoll_ctl:向 epoll 實例中添加(EPOLL_CTL_ADD)、修改(EPOLL_CTL_MOD)或刪除(EPOLL_CTL_DEL)需要監視的文件描述符及其關心的事件。這些信息由內核維護,不需要重復傳遞。

  3. epoll_wait:阻塞等待已注冊的文件描述符上發生就緒事件。與 selectpoll 不同,epoll_wait 僅返回那些已經就緒的文件描述符,而不是所有被監視的描述符。

主要特點

  • 高效性:

    • 事件驅動:內核負責跟蹤FD的狀態,當FD就緒時,會將其放入一個就緒列表中。epoll_wait 只需檢查此列表。

    • 減少數據拷貝:FD集合由內核管理,epoll_wait 調用時無需拷貝整個FD集合。

    • 無需遍歷:應用程序直接從 epoll_wait 的返回中獲取就緒的FD列表,避免了輪詢。

  • 支持邊緣觸發 (ET) 和水平觸發 (LT):

    • LT (Level Triggered, 默認):只要FD處于就緒狀態,epoll_wait 就會通知。

    • ET (Edge Triggered):僅當FD狀態從未就緒變為就緒時通知一次。這要求應用程序一次性處理完所有可用數據,編程更復雜,但能進一步減少 epoll_wait 的調用次數。

  • Linux 特有:不具備跨平臺性。

舉例epoll 就像一個現代化的智能快遞柜系統。快遞員(內核)把包裹(數據)放進柜子(FD就緒)后,系統會自動給收件人(應用程序)發送一條取件碼(epoll_wait 返回就緒的FD)。收件人憑碼直接取件,無需檢查每個柜子。

三、異步I/O模型:IOCP (Windows Specific)

異步I/O (Asynchronous I/O) 模型與I/O多路復用有本質區別。在異步I/O中,應用程序發起一個I/O操作后立即返回,不等待操作完成。操作系統內核負責完成整個I/O過程(包括將數據從內核空間拷貝到用戶指定的緩沖區),并在操作完成后通過特定機制通知應用程序。

IOCP (I/O Completion Ports)

一句話介紹IOCP 是 Windows 平臺上一種高效、可伸縮的異步I/O模型,專為處理大量并發I/O操作設計。

工作機制

  1. 創建完成端口:應用程序首先創建一個I/O完成端口 (CreateIoCompletionPort)。

  2. 關聯設備句柄:將需要進行異步I/O操作的設備句柄(如套接字、文件句柄)與該完成端口關聯。

  3. 發起異步I/O操作:應用程序調用異步I/O函數(如 ReadFile, WriteFile, WSASend, WSARecv),并提供一個 OVERLAPPED 結構和一個可選的完成鍵。這些函數會立即返回,表示操作已成功提交給操作系統。

  4. 操作系統處理:操作系統內核在后臺執行實際的I/O操作。

  5. 完成通知:當I/O操作完成(或失敗)后,操作系統會將一個包含操作結果和 OVERLAPPED 結構指針的“完成包”排入與設備句柄關聯的完成端口隊列中。

  6. 獲取完成狀態:應用程序的工作線程調用 GetQueuedCompletionStatus 函數,該函數會阻塞等待,直到完成端口隊列中有完成包。獲取到完成包后,線程便可以處理已完成的I/O操作結果(數據已在用戶緩沖區)。

主要特點

  • 真正的異步:應用程序不參與實際的I/O數據傳輸過程,僅發起請求和處理完成通知。

  • 高效的線程管理IOCP 能夠與線程池良好集成。操作系統會根據I/O負載和CPU核心數量智能地調度和喚醒工作線程,避免了過多的線程創建和上下文切換。

  • 高吞吐量和伸縮性:非常適合構建高性能服務器應用。

  • Windows 特有:不具備跨平臺性。

舉例IOCP 就像一個大型中央廚房的外賣系統。顧客(應用程序)通過App下單(發起異步I/O),然后就可以去做別的事情了。中央廚房(操作系統)負責烹飪并打包(執行I/O)。菜品完成后,系統會通知騎手(工作線程)去指定的取餐點(完成端口)取餐并配送(處理完成的I/O)。騎手們被高效地調度,確保外賣準時送達。


四、總結

特性selectpollepoll (Linux)IOCP (Windows)
模型同步I/O多路復用同步I/O多路復用同步I/O多路復用異步I/O
核心思想監視FD,等待就緒通知監視FD,等待就緒通知高效監視FD,僅返回就緒FD發起I/O,等待操作完成通知
數據傳輸程序在收到通知后自行讀寫程序在收到通知后自行讀寫程序在收到通知后自行讀寫內核完成數據傳輸
效率低,受FD數量和輪詢限制一般,不受FD數量限制,但仍需輪詢高,事件驅動,無需輪詢非常高,內核級異步,線程調度優化
跨平臺性良好較好差 (Linux)差 (Windows)

選擇哪種技術取決于具體的應用場景、目標平臺以及對性能和并發能力的要求。對于需要跨平臺且并發要求不極端的情況,selectpoll 可能是簡單選擇。對于Linux平臺下追求極致性能的高并發服務器,epoll 是首選。對于Windows平臺下的高性能服務器,IOCP 提供了強大的異步處理能力。

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

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

相關文章

microsoft中word如何添加個人簽名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入簽名圖片 圖片格式選擇裁剪合適的大小 使用的簽名如果不是白色紙張的話可以重新著色 依次點擊圖片格式——顏色——重新著色——黑白50% 設置透…

linux初識--基礎指令

Linux下基礎指令 ls 指令 語法: ls [ 選項 ] [ ?錄或?件 ] 功能:對于?錄,該命令列出該?錄下的所有??錄與?件。對于?件,將列出?件名以及其他信 息。 常?選項: -a 列出?錄下的所有?件,包括以…

實戰:Dify智能體+Java=自動化運營工具!

我們在運營某個圈子的時候,可能每天都要將這個圈子的“熱門新聞”發送到朋友圈或聊天群里,但依靠傳統的實現手段非常耗時耗力,我們通常要先收集熱門新聞,再組裝要新聞內容,再根據內容設計海報等。 那怎么才能簡化并高…

RabbitMQ可靠傳輸——持久性、發送方確認

一、持久性 前面學習消息確認機制時,是為了保證Broker到消費者直接的可靠傳輸的,但是如果是Broker出現問題(如停止服務),如何保證消息可靠性?對此,RabbitMQ提供了持久化功能: 持久…

(Java基礎筆記vlog)Java中常見的幾種設計模式詳解

前言: 在 Java 編程里,設計模式是被反復使用、多數人知曉、經過分類編目的代碼設計經驗總結。他能幫助開發者更高效地解決常見問題,提升代碼的可維護性、可擴展性和復用性。下面介紹Java 中幾種常見的設計模式。 單例模式(Singlet…

(8)Spring Boot 原生鏡像支持

Spring Boot 原生鏡像支持 ?? 點擊展開題目 在Spring Boot 3.x中,如何設計一個支持GraalVM原生鏡像的微服務?需要特別注意哪些限制? ?? Spring Boot 3.x 原生鏡像概述 Spring Boot 3.x 通過 Spring Native 項目提供了對 GraalVM 原生鏡像的一流支持,使開發者能夠將 S…

不使用SOAP,從PDF表單連接數據庫

不使用SOAP協議,通過XFDF格式實現PDF表單與數據庫交互的方法。該方法兼容免費的Adobe Reader,且無需特殊權限設置。 背景與問題 歷史方案: Adobe曾提供ADBC接口(基于ODBC),但在Acrobat 9后被移除。SOAP方案在免費版Rea…

HTTP由淺入深

文章目錄 概述特點URL HTTP 與 HTTPS概述HTTP 工作原理HTTPS 的作用區別總結 請求報文請求行常見請求方法請求頭請求體Content-Type 詳解常見場景 Content-Type 對應關系 響應報文響應行狀態碼詳解1xx:信息響應(Informational)2xx&#xff1a…

Redis淘汰策略

Redis有八種淘汰策略 noeviction :不進行淘汰,直接報錯。allkeys-lru :隨機淘汰最久未使用的鍵。volatile-lru :從設置了過期時間的鍵中,隨機淘汰最久未使用的鍵。allkeys-random :隨機淘汰某個鍵。volati…

Maven打包SpringBoot項目,因包含SpringBootTest單元測試和Java預覽版特性導致打包失敗

SpringBoot啟用Java預覽版特性&#xff08;無測試類&#xff09; 在pom.xml文件中加入以下配置表示啟用Java預覽版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…

Makefile快速入門

簡介?&#xff1a; ? Makefile? 是一種用于自動化構建和管理軟件項目的工具文件&#xff0c;通常與 make 命令配合使用。它通過定義?規則?&#xff08;rules&#xff09;來指定如何從源文件生成目標文件&#xff08;如可執行程序或庫&#xff09;&#xff0c;并自動…

RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭

視頻講解&#xff1a;RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭_嗶哩嗶哩_bilibili RISC-V 開發板 MUSE Pi Pro OpenCV結合Gstreamer實時顯示CSI攝像頭 安裝opencv相關庫 sudo apt install libopencv-dev python3 python3-opencv 測試使用的CSI攝像頭…

如何用JAVA手寫一個Tomcat

一、初步理解Tomcat Tomcat是什么&#xff1f; Tomcat 是一個開源的 輕量級 Java Web 應用服務器&#xff0c;核心功能是 運行 Servlet/JSP。 Tomcat的核心功能&#xff1f; Servlet 容器&#xff1a;負責加載、實例化、調用和銷毀 Servlet。 HTTP 服務器&#xff1a;監聽端口…

短劇系統開發與抖音生態融合:短視頻時代的新風口與商業機遇

在短視頻內容井噴的時代&#xff0c;“短劇”作為一種新興內容形態&#xff0c;正以驚人的速度搶占用戶注意力。抖音、快手等平臺日均播放量破億的短劇作品&#xff0c;不僅催生了新的內容創作風口&#xff0c;更推動了短劇系統開發的巨大市場需求。本文將深度解析短劇系統開發…

《云原生安全攻防》-- K8s日志審計:從攻擊溯源到安全實時告警

當K8s集群遭受入侵時&#xff0c;安全管理員可以通過審計日志進行攻擊溯源&#xff0c;通過分析攻擊痕跡&#xff0c;我們可以找到攻擊者的入侵行為&#xff0c;還原攻擊者的攻擊路徑&#xff0c;以便修復安全問題。 在本節課程中&#xff0c;我們將介紹如何配置K8s審計日志&am…

3dczml時間動態圖型場景

在cesium中我們了可以使用czml數據來生成可以隨時間變化而變化的物體. 首先導入czml數據 設置時間范圍 id: "point" //物體在什么時間范圍可用 availability:"2012-08-04T16:00:00Z/2012-08-04T16:05:00Z"position:{ //設置物體的起始時間 epoch:"…

超小多模態視覺語言模型MiniMind-V 訓練

簡述 MiniMind-V 是一個超適合初學者的項目&#xff0c;讓你用普通電腦就能訓一個能看圖說話的 AI。訓練過程就像教小孩&#xff1a;先準備好圖文材料&#xff08;數據集&#xff09;&#xff0c;教它基礎知識&#xff08;預訓練&#xff09;&#xff0c;再教具體技能&#xf…

01-jenkins學習之旅-window-下載-安裝-安裝后設置向導

1 jenkins簡介 百度百科介紹&#xff1a;Jenkins是一個開源軟件項目&#xff0c;是基于Java開發的一種持續集成工具&#xff0c;用于監控持續重復的工作&#xff0c;旨在提供一個開放易用的軟件平臺&#xff0c;使軟件項目可以進行持續集成。 [1] Jenkins官網地址 翻譯&…

VPLC (VPLCnext) K8S

前序 在接觸Virtual PLCnext Control的時候&#xff0c;我想過好幾次如何將它運行在k8s上&#xff0c;由于對k8s的熟悉程度不夠&#xff0c;跌跌撞撞嘗試了很久&#xff0c;終于把vPLC部署在單機版的k8s上了。&#xff08;此教程僅為demo階段&#xff0c;此教程僅為demo階段&a…

OPC Client第5講(wxwidgets):初始界面的事件處理;按照配置文件初始化界面的內容

接上一講&#xff0c;即實現下述界面的事件處理代碼&#xff1b;并且按照配置文件初始化界面的內容&#xff08;三、&#xff09; 事件處理的基礎知識&#xff0c;見下述鏈接五、 OPC Client第3講&#xff08;wxwidgets&#xff09;&#xff1a;wxFormBuilder&#xff1b;基礎…