高級IO(五種IO模型介紹)

文章目錄

  • 一、IO為什么慢?
  • 一、阻塞IO
  • 二、非阻塞IO
  • 三、信號驅動IO
  • 四、IO多路復用
  • 五、異步IO

一、IO為什么慢?

  1. IO操作往往都是和外設交互,比如鍵盤、鼠標、打印機、磁盤。而最常見的就是內存與磁盤的交互,要知道磁盤是機械設備,需要機械運轉來存取數據,所以比較慢。
  2. IO本質是:等+拷貝時間往往消耗在等上,等待鍵盤輸入就緒、文件描述符就緒、硬件中斷就緒…

??外設就緒慢是相較于 CPU 來說的,它本身是很快,我們感知不到。
??IO的拷貝很快的,慢大部分時間都花在等上,所以接下來我們就從“等”下手,去解決IO慢的問題。

IO 效率高?單位時間內,傳輸的數據量越大,IO 效率越高。

下面講解的五種IO模型,我們從一個釣魚例子引入:

  • 張三:全神貫注的盯著魚漂,本著魚漂不動我不動的原則,盡管馬蜂撲他臉上。(阻塞)
  • 李四:不會因為魚不上鉤就緊緊盯著什么也不干,而是邊做其他事情,刷刷快手抖音,寫寫博客啥的。(非阻塞)
  • 王五(聰明人):魚竿頂部加鈴鐺,他比李四好一些,不用時不時地去看魚漂。(信號驅動)
  • 趙六(富人):拖來一卡車100支魚竿,全部用來釣魚,然后只用左右檢查是否有魚竿釣到魚。(多路復用)
    在這里插入圖片描述
  • 田七(大老板):他知道他不是喜歡釣魚,而是喜歡吃魚。派小王去釣魚,他干自己的事,到時候負責吃就行。(異步IO)

一、阻塞IO

??張三釣魚的例子就是阻塞IO,它的特點是在內核將數據準備好之前,系統調?會?直等待。所有的套接字,默認都是阻塞?式。阻塞IO是最常見的IO模型。如下應用程序與內核的交互:

在這里插入圖片描述

二、非阻塞IO

???阻塞IO:如果內核還未將數據準備好,系統調?仍然會直接返回,并且返回EWOULDBLOCK錯誤碼。
???阻塞IO往往需要程序員循環的?式反復嘗試讀寫?件描述符,這個過程稱為輪詢。這對CPU來說是較?的浪費,?般只有特定場景下才使?。

在這里插入圖片描述

阻塞和?阻塞關注的是程序在等待調?結果(消息,返回值)時的狀態。

  • 阻塞調?是指調?結果返回之前,當前線程會被掛起,調?線程只有在得到結果之后才會返回。
  • ?阻塞調?指在不能?刻得到結果之前,該調?不會阻塞當前線程。

文件默認情況下就是阻塞IO不用我們去修改,那么我們想要設置非阻塞IO要怎么做呢?

  • 方法一:在文件open打開時添加O_NONBLOCK標準位即可。
    如果在文件打開之后想要設非阻塞IO呢?
  • 方法二:使用函數fcntl,需要包含頭文件unistd.hfcntl.h
int fcntl(int fd, int cmd, ... /* arg */ );

參數:

  • fd:文件描述符(如 ```socket``、普通文件等)。
  • cmd:控制命令(如 F_GETFL、F_SETFL等)。
    • F_GETL:獲取當前文件描述符的標志,如 O_RDONLY、O_NONBLOCK等。
    • F_SETFL:設置文件描述符的標志。
  • arg:可選參數,取決于 cmd

返回值:

  • 成功時返回值取決于 cmd,F_GETFL成功時返回狀態標志符,F_SETFL成功時返回0,失敗時都返回-1
  • 失敗時返回 -1,并設置 errno(如 EBADF 無效描述符)。

獲取原標志符:int fg = fcntl(fd,F_GETFL);
設置O_NONBLOCK標志位:fcntl(fd, F_SETFL, fg | O_NONBLOCK)

??我們以read為例,當將文件設為非阻塞后,我們再去讀取數據,即使數據沒就緒,也不會把程序掛起,而是直接返回一個小于0的結果繼續往下執行。所以數據并不一定一次read就讀取到,需要我們反復去read,也就是輪詢。
??不過還有一個問題,read失敗返回值小于0,因為數據未就緒返回值也是小于0,那么我們怎么區分呢?其實這兩種結果都有不同的erron錯誤參數,到時候拿erron去匹配就行,即:

  • EWOULDBLOCK或EAGAIN:都表示數據未就緒。因為歷史版本原因所以有兩個版本,它們的值都是11,任意使用一個即可。
  • EINTR:因信號中斷導致的讀書失敗。
  • 其他:read讀取錯誤。

測試示例:

#include <fcntl.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main()
{int fd = 0;//獲取標志符int fn = fcntl(fd, F_GETFL);//增加O_NONBLOCK并設置fcntl(fd, F_SETFL, fn | O_NONBLOCK);int count = 0;while(1){char buffer[1024];int n = read(fd, buffer, sizeof(buffer)-1);if(n > 0){buffer[n] = '\0';cout<<buffer<<endl;sleep(1);}else if(n < 0){if(errno == EAGAIN || errno == EWOULDBLOCK){cout<<"文件未就緒..."<<endl;sleep(2);}else if(errno == EINTR){cout<<"信號中斷..."<<endl;continue;}else{perror("read fail\n");break;}}else{break;}}return 0;
}

三、信號驅動IO

信號驅動IO:內核將數據準備好的時候,使?SIGIO信號通知應?程序進?IO操作。

在這里插入圖片描述
工作流程

  • 注冊信號處理程序:應用進程首先使用 sigaction系統調用,建立針對特定信號(通常是 SIGIO)的信號處理程序。在這一步,進程告知內核,當特定的 I/O 事件發生時,應該觸發哪個信號處理函數。
  • 設置文件描述符:應用進程需要將相關的文件描述符(如套接字描述符)設置為信號驅動 I/O 模式,并指定該文件描述符的屬主(通常使用fcntl 系統調用的 F_SETOWN命令設置屬主為當前進程 )。這一步確保內核知道當 I/O 事件就緒時,應該向哪個進程發送信號。
  • 內核等待數據:完成上述設置后,應用進程可以繼續執行其他任務,而內核開始等待數據到達。當數據報準備好(比如有數據到達套接字 )時,內核會向應用進程發送預先設置好的信號(如SIGIO )。
  • 信號處理:應用進程接收到SIGIO 信號后,會暫停當前正在執行的任務,轉而執行之前注冊的信號處理程序。在信號處理程序中,通常會調用諸如recvfrom 這樣的函數來讀取數據。在數據從內核拷貝到用戶空間的應用緩沖區期間,進程會阻塞(這是信號處理函數內部執行具體 I/O 操作時的阻塞 ),直到數據拷貝完成。
  • 處理數據:數據讀取完成后,信號處理程序執行結束,進程恢復之前被暫停的任務,或者開始對讀取到的數據進行處理。

四、IO多路復用

??IO多路復用允許單個線程/進程同時監控多個文件描述符(如套接字、管道等)的 I/O 事件,并在任一描述符就緒時進行讀寫操作。它是高并發網絡編程的核心技術之一。是真正意義上的高效 I/O 處理機制,它在單位時間內增加了傳輸效率,而其他四個只是在利用等的時間而已,并沒有提高IO效率。
在這里插入圖片描述

核心思想

  • 統一監控:通過系統調用(如select、poll、epoll)一次性注冊多個文件描述符,由內核通知哪些描述符已就緒(可讀/可寫/異常)。
  • 避免阻塞輪詢:無需為每個描述符創建獨立線程,節省資源。
  • 單線程高并發:一個線程即可處理成千上萬的連接(如 Nginx、Redis 的底層模型)。

??關于IO多路復用的很重要,涉及select/poll/epoll,有繁多的細節和復雜的底層邏輯,統一放在下一章進行講解。

五、異步IO

在這里插入圖片描述

??核心思想是 “發起 I/O 請求后立即返回,由內核完成所有操作(包括數據拷貝),并通過回調或信號通知進程結果”。與同步 I/O 不同,進程無需等待 I/O 完成即可繼續執行其他任務,真正實現 非阻塞 和 完全異步。

異步IO特性

  • 非阻塞調用:調用 I/O 函數(如 aio_read)立即返回,不阻塞進程。
  • 內核全權處理:內核負責數據準備、拷貝到用戶空間,全程無需進程參與。
  • 通知機制:操作完成后,內核通過回調、信號或事件通知進程。
  • 全程無等待:進程從發起請求到獲取結果均無需阻塞,最大化利用 CPU。
IO模型控制方式優勢劣勢
阻塞 I/O進程阻塞等待數據編程簡單無法并發處理多 I/O
非阻塞 I/O輪詢檢查數據是否就緒可同時處理其他任務輪詢消耗 CPU
I/O多路復用select/epoll統一監控高并發支持
信號驅動 I/O內核信號通知無輪詢,延遲低信號處理復雜,不適合高頻場景
異步 I/O (AIO)內核完成所有操作后回調真正的異步,全程無阻塞實現復雜,部分系統支持不完善

非常感謝您能耐心讀完這篇文章。倘若您從中有所收獲,還望多多支持呀!
在這里插入圖片描述

?

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

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

相關文章

第十二節:粒子系統:海量點渲染

第十二節&#xff1a;粒子系統&#xff1a;海量點渲染 引言 粒子系統是創造動態視覺效果的神器&#xff0c;從漫天繁星到熊熊火焰&#xff0c;從魔法特效到數據可視化&#xff0c;都離不開粒子技術。Three.js提供了強大的粒子渲染能力&#xff0c;可輕松處理百萬級粒子。本文將…

LeetCode Day5 -- 二叉樹

目錄 1. 啥時候用二叉樹&#xff1f; &#xff08;1&#xff09;典型問題 &#xff08;2&#xff09;核心思路 2. BFS、DFS、BST 2.1 廣度優先搜索BFS &#xff08;1&#xff09;適用任務 &#xff08;2&#xff09;解決思路??&#xff1a;使用隊列逐層遍歷 2.2 深度…

<c1:C1DateTimePicker的日期時間控件,控制日期可以修改,時間不能修改,另外控制開始時間的最大值比結束時間小一天

兩個時間控件 <c1:C1DateTimePicker Width"170" EditMode"DateTime" CustomDateFormat"yyyy-MM-dd" CustomTimeFormat"HH:mm:ss" Style"{StaticResource ListSearch-DateTimePicker}" x:Name"dateTimePicker"…

文件完整性監控工具:架構和實現

文件完整性監控(FIM)作為一道關鍵的防御層&#xff0c;確保系統和網絡中文件及文件夾的完整性與安全性。文件完整性監控工具通過監控關鍵文件的變更并檢測未經授權的修改&#xff0c;提供關于潛在安全漏洞、惡意軟件感染和內部威脅的早期警報。為了使文件完整性監控工具發揮實效…

Linux信號量和信號

1.溫故知新上一篇博客&#xff0c;我們又知道了一種進程間通信的方案&#xff1a;共享內存。它是在物理內存中用系統調用給我們在物理內存開辟一個共享內存&#xff0c;可以由多個進程的頁表進行映射&#xff0c;共享內存不和管道一樣&#xff0c;它的生命周期是隨內核的&#…

騰訊測試崗位面試真題分析

以下是對騰訊測試工程師面試問題的分類整理、領域占比分析及高頻問題精選&#xff08;基于??92道問題&#xff0c;總出現次數118次??&#xff09;。問題按??7大技術領域??劃分&#xff0c;高頻問題標注優先級&#xff08;1-5&#x1f31f;&#xff09;&#xff1a; 不…

全面解析遠程桌面:功能實現、性能優化與安全防護全攻略

遠程桌面技術已成為工作與生活中不可或缺的協作工具&#xff0c;但在實際應用中&#xff0c;用戶常遇到連接失敗、卡頓延遲、安全隱患等問題。本文從遠程桌面功能原理、網絡與性能優化、安全防護策略、跨平臺兼容性等角度&#xff0c;詳細解析常見問題的解決方案&#xff0c;并…

【問題】Mybatis-plus框架使用@Select注解編寫查詢SQL,json字段查詢轉換失敗

問題描述在使用mybaits-plus的時候定義的Mapper接口實現了BaseMapper&#xff0c;沒有編寫Mapper對應的xml&#xff0c;大部分查詢使用框架的接口進行查詢基本屬性返回都是正常&#xff0c;復雜對象在sql中會進行查詢&#xff0c;但是返回對象中卻未包含相關屬性。問題原因 沒有…

Python多線程實現大文件下載

Python多線程實現大文件下載 在互聯網時代&#xff0c;文件下載是日常操作之一&#xff0c;尤其是大文件&#xff0c;如軟件安裝包、高清視頻等。然而&#xff0c;網絡條件不穩定或帶寬有限時&#xff0c;下載速度會變得很慢&#xff0c;令人抓狂。幸運的是&#xff0c;通過多線…

【R語言】RStudio 中的 Source on Save、Run、Source 辨析

RStudio 中的 Source on Save、Run、Source 辨析 在使用 RStudio 進行 R 語言開發時&#xff0c;我們會在主界面左上角看見三個按鈕&#xff1a;Source on Save、Run、Source 。 本文將帶你從概念、使用方法、快捷鍵、使用場景以及注意事項等方面詳細解析這三個功能。 文章目錄…

藍橋杯算法之搜索章 - 4

目錄 文章目錄 前言 一、記憶化搜索 二、題目概略 三、斐波拉契數 四、Function 五、天下第一 六、滑雪 總結 親愛的讀者朋友們&#xff0c;大家好啊&#xff01;不同的時間&#xff0c;相同的地點&#xff0c;今天又帶來了關于搜索部分的講解。接下來我將接著我前面文章的內容…

抗量子加密技術前瞻:后量子時代的密碼學革命

目錄抗量子加密技術前瞻&#xff1a;后量子時代的密碼學革命1. 量子計算威脅現狀1.1 量子霸權里程碑1.2 受威脅算法1.3 時間緊迫性2. 抗量子密碼學體系2.1 技術路線對比2.2 數學基礎革新3. 標準化進程3.1 NIST PQC標準化時間線3.2 當前推薦算法4. 技術實現方案4.1 Kyber密鑰交換…

基于STM32設計的礦山環境監測系統(NBIOT)_262

文章目錄 一、前言 1.1 項目介紹 【1】開發背景 【2】研究的意義 【3】最終實現需求 【4】項目硬件模塊組成 1.2 設計思路 【1】整體設計思路 【2】上位機開發思路 1.3 項目開發背景 【1】選題的意義 【2】摘要 【3】國內外相關研究現狀 【5】參考文獻 1.4 開發工具的選擇 【1】…

電腦如何安裝win10專業版_電腦用u盤安裝win10專業版教程

電腦如何安裝win10專業版&#xff1f;電腦還是建議安裝win10專業版。Win分為多個版本&#xff0c;其中家庭版&#xff08;Home&#xff09;和專業版&#xff08;Pro&#xff09;是用戶選擇最多的兩個版本。win10專業版在功能以及安全性方面有著明顯的優勢&#xff0c;所以電腦還…

多語言文本 AI 情感分析 API 數據接口

多語言文本 AI 情感分析 API 數據接口 AI / 文本處理 AI 模型快速分析文本情感傾向 多語言文本 / 情感分析。 1. 產品功能 支持多語言文本情感分析&#xff1b;基于特定 AI 模型&#xff0c;快速識別文本情感傾向&#xff1b;適用于評論分析、輿情監控等場景&#xff1b;全接…

【R語言】R語言的工作空間映像(workspace image,通常是.RData)詳解

R語言的工作空間映像&#xff08;.RData&#xff09;詳解 在使用 R 語言時&#xff0c;你可能會注意到&#xff0c;每次退出 R 會彈出一個提示&#xff1a; Save workspace image? [y/n/c] 如果你使用的是 Rstudio 這個 IDE 來進行R語言的開發&#xff0c;那么可能彈出的提示…

在線 A2C實踐

在線 A2C&#xff08;Actor-Critic&#xff09;算法在推薦系統中的實踐&#xff0c;核心是將推薦過程建模為實時交互的強化學習問題&#xff0c;通過 Actor 生成推薦策略、Critic 評估策略價值&#xff0c;實現 “決策 - 反饋 - 更新” 的閉環。從樣本設計到最終上線&#xff0…

Eclipse RCP產品動態模塊設計

文章目錄 遇到問題具體實踐效果演示應用下載 遇到問題 如果你是一個To C產品的設計者&#xff0c;勢必會遇到用戶需求高度分化的場景&#xff0c;隨之而來的是繁雜的功能列表&#xff0c;如何讓用戶只接觸與其任務直接相關的功能&#xff0c;隱藏無關元素&#xff1f; 具體實…

NLP自然語言處理: FastText工具與遷移學習基礎詳解

FastText工具與遷移學習基礎詳解 一、知識框架總覽 FastText工具核心功能與應用場景FastText模型架構與工作原理層次Softmax加速機制哈夫曼樹概念與構建方法 二、FastText工具核心解析 2.1 功能定位 雙重核心功能 文本分類&#xff1a;可直接用于文本分類任務&#xff0c;快速生…

uni-app 生命周期詳解

概述 uni-app 基于 Vue.js 框架開發&#xff0c;其生命周期包含了三個層面&#xff1a; 應用生命周期&#xff1a;App.vue 的生命周期頁面生命周期&#xff1a;各個頁面的生命周期Vue 組件生命周期&#xff1a;Vue.js 原生的組件生命周期 這三種生命周期在不同場景下會按特定順…