淺談linux緩沖區的認識!

今天來為大家分享一波關于緩沖區的知識!那么既然我們要談緩沖區,那么就得從是什么?為什么?有什么作用這幾個方面來談論一下緩沖區!然后再通過一些代碼來更加深刻的理解緩沖區的知識!

引言:

是什么?

從最簡單的理解方面來,我們可以將緩沖區理解成一塊內存!那么這塊內存是從哪里來的呢?在linux中一般我們所說的緩沖區都是由C提供的語言級別的緩沖區!

干什么的?

那么緩沖區的作用主要是用來干什么的呢?可以從我們生活中的例子來理解!假設你的朋友小張下個月就要過生日了,你要送他一個生日禮物!但是你們兩個距離很遠!一個在西藏,一個在海南!如果讓你自行將生日禮物送給他,那么無疑將會浪費你的很多成本!但是現實中存在快遞站,只需要你下樓將禮物交付給快遞站,然后由快遞站代替你送過去即可!那么在本例子內,快遞站的作用就是一個緩沖區的作用!


為什么要存在緩沖區?

根據上面提到的例子,很容易理解,因為有了快遞站的存在,使我們方便了很多!所以類似于此,緩沖區存在的意義就是為了提高效率,減少我們的成本!


下面通過一段代碼來證明一下緩沖區確實存在!

我們用戶通常寫程序在屏幕上打印一段文字的時候!其中就利用到了緩沖區!例如下面這個例子!

運行這段程序之后,顯示屏上并沒沒有立刻打印出“hello linux”,這是為什么呢?根據我們所了解到的知識,程序是自上向下運行的,運行到sleep的時候,printf語句一定是執行過了,但是為什么沒有打印出結果呢?根據此例子可以充分的證明緩沖區的存在!!既然證明了緩沖區的存在,那么我們將來一步一步的進行分析緩沖區的相關知識1

那么從系統角度來將該如何理解的呢?

從操作系統角度上來看!用戶輸入一段指令,該指令并沒有直接傳遞到內核文件內存中!而是將用戶輸入的指令存放到了C提供的語言級別的緩沖區內!然后在C語言的緩沖區中經過刷新之后!再傳遞到內核結構中的文件緩沖區中!最后系統會定期的將內存的數據刷新到磁盤中!此階段也可以稱之為刷新!在此,我們提到了兩個緩沖區,一個是用戶層的C語言提供的語言級別的緩沖區,一個是內核結構中的內核文件緩沖區!一般我們所考慮的都是C語言提供的語言級別的緩沖區!


緩沖區的一些特性:

根據緩沖區能夠存儲一定的數據可以推出:緩沖區一定存在著刷新的方式!

1.無緩沖(立即刷新!)

2.行緩沖(行刷新!)

一般對于顯示器文件,都是基于行緩沖的模式!

3.全緩沖(存放滿然后進行刷新!)

對于磁盤文件,都是基于全緩沖的方式!


那么根據以上的特征,緩沖區也會有著特殊的情況!

1.強制刷新!

2.進程退出后,會自動進行刷新!(無論是否滿足刷新的條件!)


實例:充分理解緩沖區

下面通過一段代碼來充分理解緩沖區中的行緩沖和全緩沖!

上面代碼運行過后,每行代碼都打印了出來!這是為什么呢?剛才不是還說是存在緩沖區的么?其實不難理解,因為每段代碼都有了\n換行符,強制讓緩沖區內的數據進行刷新!所以數據都原樣的打印了出來!!

那么將上面的代碼經過簡單的修改就會出現另外一種結果!

經過上面代碼簡單的修改,我們發現C函數的調用都打印了兩次,而是用系統調用的write確只調用了一次!這是為什么呢?其實很簡單!

我們可以看出,我們將輸出結果由原來的行緩沖轉化成了全緩沖(因為將結果打印到了log.txt文本文件中,文本文檔默認為全緩沖的刷新方式!)所以只有當將緩沖區填滿的時候,才會進行刷新!才能打印到顯示屏中!又因為調用了fork函數,創建了新的子進程!根據fork的特性會繼承父進程的代碼和數據塊!因為此時代碼仍然在緩沖區內!所以子進程也會繼承這些相同的代碼和數據塊!然后當一個進程結束后,就會發生寫時拷貝!這是因為當一個進程退出的時候,一般都會對緩沖區的數據進行刷新,那么算不算清空或寫入的操作呢?答案是肯定的!當時算!所以就會發生寫時拷貝!所以可以推出,一旦一個進程退出,那么就會發生寫時拷貝!

根據上圖結果看出,系統調用write只打印了一次!從這里可以推出:write沒用使用C語言的緩沖區!因為C語言的一些函數,大多都是對系統調用的封裝!大多都是因為封裝的原因!而導致他們使用C提供的緩沖區!而系統調用處于內核級別,在用戶級別的下面,直接將數據寫入到內核文件系統中!所以不使用C提供的緩沖區!

實例中的主要知識點:

1.當我們直接向顯示器打印的時候,顯示器文件的刷新方式是行刷新!而是我們的代碼輸出的所有字符串,都有\n,fork之前,數據已經全部被刷新!包括systemcall!

2.重定向到log.txt之后,本質是向磁盤文件中寫入(而不再是顯示器里面!),我們系統對于數據的刷新方式已經由行刷新轉化到了全刷新的方式!變成了全緩沖!

3.全緩沖意味著緩沖區變大,實際寫入的簡單數據,不足以將緩沖區填滿!fork執行的時候,數據依然在緩沖區內部!

4.我們目前所談的緩沖區,是和操作系統沒有關系的!只能和C語言本身有關!!

5.C/C++提供的緩沖區,里面保存的一定是用戶的數據!其屬于當前進程運行的數據!但是如果當把數據交付給OS,這些數據就屬于OS了,不再屬于該進程了!

6.當進程退出的時候,一般會進行刷新緩沖區,即使我們的數據沒有滿足刷新條件!


證明緩沖區的存在以及其在內核中的結構!

既然我們都講了這么多關于緩沖區的知識了,那么我們確實已經知道了緩沖區真實存在!那么能否讓我看一看其到底是什么樣子的呢?

通過以上函數,我們可以發現,大多的輸入輸出操作,以及文件的操作都用到了FILE該結構體!那么該結構體之中我們之前知道其包含了文件描述符fd,那么其是否介意再包含一個緩沖區的成員變量呢?答案是當然不介意的啦!

我們可以通過對FILE的觀察來看一下緩沖區的真實存在!

我們通過grep指令來查看FILE的路徑!然后在FILE內部繼續進行查找,最后看到FILE內部有我們熟悉的文件描述符_fileno,以及我們今天所講的緩沖區的內容!


至此,本文關于緩沖區的介紹到此為止,希望讀完本篇文章,能對讀者有一定的收獲!

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

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

相關文章

【C++ Primer Plus學習記錄】邏輯表達式

一、邏輯OR運算符:|| 如果表達式中的任何一個或全部都為true(或非零),則得到的表達式的值為true;否則,表達式的值為false。 ||的優先級比關系運算符低。 C規定,||運算符是個順序點。即&#…

Navicat 技術指引 | 適用于 GaussDB 分布式的日志查詢與配置設置

Navicat Premium(16.3.3 Windows 版或以上)正式支持 GaussDB 分布式數據庫。GaussDB 分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能,還提供強大的高階功能(如模型、結…

文獻計量學方法與應用、主題確定、檢索與數據采集、VOSviewer可視化繪圖、Citespace可視化繪圖、R語言文獻計量學繪圖分析

目錄 一、文獻計量學方法與應用簡介 二、主題確定、檢索與數據采集 三、VOSviewer可視化繪圖 四、Citespace可視化繪圖 五、R語言文獻計量學繪圖分析 六、論文寫作 七、論文投稿 更多應用 文獻計量學是指用數學和統計學的方法,定量地分析一切知識載體的交叉…

AWS攻略——使用中轉網關(Transit Gateway)連接不同區域(Region)VPC

文章目錄 Peering方案Transit Gateway方案環境準備創建Transit Gateway Peering Connection接受邀請修改中轉網關路由修改被邀請方中轉網關路由修改邀請方中轉網關路由 測試修改Public子網路由 知識點參考資料 區別于 《AWS攻略——使用中轉網關(Transit Gateway)連接同區域(R…

C++_函數重載

前言: 函數重載的意思就是可以有多個同名函數存在,但是這些同名函數的參數列表有著不同情形,以便區分。在C中,支持在同一作用域下可以聲明、定義多個同名函數,但是這些函數的形參類型,類型順序以及參數個數…

AI大規模專題報告:大規模語言模型從理論到實踐

今天分享的AI系列深度研究報告:《AI大規模專題報告:大規模語言模型從理論到實踐》。 (報告出品方:光大證券) 報告共計:25頁 大規模語言模型基本概念 語言是人類與其他動物最重要的區別,而人類…

深入理解 Promise:前端異步編程的核心概念

深入理解 Promise:前端異步編程的核心概念 本文將幫助您深入理解 Promise,這是前端異步編程的核心概念。通過詳細介紹 Promise 的工作原理、常見用法和實際示例,您將學會如何優雅地處理異步操作,并解決回調地獄問題。 異步編程和…

Linux的硬盤管理

本章主要介紹Linux磁盤管理 了解分區的概念對硬盤進行分區swap分區的管理 新的硬盤首先需要對其進行分區和格式化,下面來了解一下硬盤的結構,如圖 硬盤的磁盤上有一個個圈,每兩個圈組成一個磁道。從中間往外發射線,把每個磁道分…

信息系統工程的基本概念

系統是由相互作用和相互依賴的若干部分,按一定規律結合成的、具有特定功能的有機整體。系統有下述特性: (1)集合性。系統是由許多元素有機地組成的整體。每個元素服從整體,追求全局最優。 (2)相…

springboot3遠程調用

RPC 兩個服務器之間的調用 遠程請求 內部服務之間的調用 可以通過 cloud 注冊中心 openfeign等 外部服務的調用 http請求 外部協議 api:遠程接口 sdk:本地調用 調用阿里云的天氣請求

深度學習|詞嵌入的演變

文本嵌入,也稱為詞嵌入,是文本數據的高維、密集向量表示,可以測量不同文本之間的語義和句法相似性。它們通常是通過在大量文本數據上訓練 Word2Vec、GloVe 或 BERT 等機器學習模型來創建的。這些模型能夠捕獲單詞和短語之間的復雜關系&#x…

要求CHATGPT高質量回答的藝術:提示工程技術的完整指南—第 27 章:如何避開和繞過所有人工智能內容檢測器

要求CHATGPT高質量回答的藝術:提示工程技術的完整指南—第 27 章:如何避開和繞過所有人工智能內容檢測器 使用高易錯性和突發性方法 與人工智能生成的文本相比,人類寫作往往具有更多的突發性,這是由于人類往往比人工智能生成的文…

【開源】基于Vue+SpringBoot的陜西非物質文化遺產網站

文末獲取源碼,項目編號: S 065 。 \color{red}{文末獲取源碼,項目編號:S065。} 文末獲取源碼,項目編號:S065。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 設計目標2.2 研究內容2.3 研究方法與…

GEE中Landsat中大改變——Landsat Collection 1 到 Collection 2 影像集合遷移

Landsat Collection 1 到 Collection 2 遷移 本指南提供了從Landsat Collection 1 數據切換 到 Collection 2 數據的說明。自 2022 年以來,集合 2 已在 Earth Engine 中完全可用, 自 2021 年 12 月 31 日以來,美國地質調查局 (USGS) 未生成集合 1 數據。Landsat Collection …

3D點云:平面模型上提取凸(凹)多邊形方法

目錄 一、實現原理 二、實現代碼 三、運行結果 一、實現原理 首先要在點云中提取出潛在平面,對原始點云數據進行濾波,根據提取出的平面模型系數從濾波后的點云進行投影,然后根據投影后的點云計算其對應的二維凹(凸)多邊形。 二、實現代碼 #in

webrtc 設置不獲取鼠標 啟用回聲消除

數 getDisplayMedia()(屬于 navigator.mediaDevices 的一部分)與 getUserMedia() 類似,用于打開顯示內容(或部分內容,如窗口)。返回的 MediaStream 與使用 getUserMedia() 時相同。 顯示鼠標與否 getDisp…

案例064:基于微信小程序的考研論壇設計

文末獲取源碼 開發語言:Java 框架:SSM JDK版本:JDK1.8 數據庫:mysql 5.7 開發軟件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序開發軟件:HBuilder X 小程序…

正則表達式(7):轉義符

正則表達式(7):正則表達式(5):轉義符 本博文轉載自 此處,我們來認識一個常用符號,它就是反斜杠 “\” 反斜杠有什么作用呢?先不著急解釋,先來看個小例子。 …

【游戲引擎 - C#腳本系統】6、C#端調用C++函數

強烈建議閱讀Mono官方文檔 有mono庫提供的API&#xff0c;這個過程非常簡單&#xff0c;通過mono在C中注冊函數&#xff0c;然后在C#中聲明和調用這些函數 1、在C中注冊Internal Call&#xff1a; C代碼中定義一個函數 static void CppFunc() {std::cout << "這…

24 遞歸求解二叉樹打家劫舍

問題描述&#xff1a;在上次大街萬一條街道之后和一圈房屋后&#xff0c;小偷又發現了一個新的可行竊的地區。這個地區只有一個入口&#xff0c;我們稱之為根。除了根之外&#xff0c;每棟房子有且只有一個父房子與之項鏈&#xff0c;一番偵查之后&#xff0c;聰明的小偷意識到…