從硬件角度理解“Linux下一切皆文件“,詳解用戶級緩沖區

目錄

前言

一、從硬件角度理解"Linux下一切皆文件"

從理解硬件是種“文件”到其他系統資源的抽象

二、緩沖區

1.緩沖區介紹

2.緩沖區的刷新策略

3.用戶級緩沖區

這個用戶級緩沖區在哪呢?

解釋關于fork再加重定向“>”后數據會打印兩份的原因

4.內核緩沖區簡介

總結



前言

"Linux下一切皆文件",這是Linux的一個基本設置理念同時也是Linux的設計哲學所在。

這篇博客,筆者首先總結一下我自學習Linux以來,到目前自己對“Linux下一切皆文件”的感悟和理解,其次再討論Linux中的緩沖區機制。


提示:以下是本篇文章正文內容,下面案例可供參考

一、從硬件角度理解"Linux下一切皆文件"

首先需要再次明確Linux操作系統的主要目的或者作用:

對上,方便用戶使用——為用戶提供穩定的、高效的、安全的使用環境。

對下,管理好計算機繁雜的軟硬件資源;

其次需要明確的是文件無外乎由兩部分構成:內容和屬性

內容決定文件“是什么”(數據含義)。

屬性決定文件的“如何用”(權限、存儲、類型)。

比如一個普通文件:

他的內容是文本、二進制數據;

他的屬性是文件名、權限、大小、時間戳等。

我們可以通過write、read等修改文件內容,也可以用chmod函數修改文件的權限等屬性。

初識Linux:常見指令介紹,文件權限的更改,以及粘滯位的理解-CSDN博客

那么思維發散一下,我們能否將這些硬件的自身狀態、操作方法抽象為“內容+屬性”,并用統一的接口修改這些硬件呢?

已知的是Linux似乎正是將系統資源(如硬件設備等)抽象為文件,提供統一的文件操作接口(open,?read,?write,?close等)。使得無論操作對象是普通文件、目錄、設備,用戶都可以通過相同的文件系統與之交互。

從理解硬件是種“文件”到其他系統資源的抽象

對于計算機上諸多的硬件資源,我目前認為操作系統通過:先整理,再管理的方法管理這些硬件。

所謂先整理,在管理。這是筆者從進程PCB的創建受到的啟發。OS為方便管理不同的進程會為其創建PCB,其中包含著進程的所有屬性信息,那管理硬件是不是也可以通過創建某種數據結構來實現管理呢?

假設OS為方便管理各種硬件資源會為其創建某種數據結構——這里想象成某種結構體struct file,該結構體中記錄著該硬件的各種屬性信息和行為函數——即IO操作。

通過對馮諾依曼體系結構的抽象,將計算機抽象為存儲器和其他。這個其他中包括cpu和各種硬件設備,這么劃分的原因是這些硬件都要與內存進行IO操作。我們不妨暫將所有硬件的IO操作抽象為兩個函數read( )和write( )。

通過上述兩點,創建一個struct file結構體,其中有著各硬件的狀態信息和函數行為:

struct file
{//內容int type;int status;……//屬性int (*write)();//函數指針int (*read)();……
}

那么將每個硬件file實例化(與多態有些相似),再通過一個數據結構如鏈表將這些硬件的struct對象管理起來,如鏈表。

綜上,當站在上層視角來看,這些硬件都是一種統一的數據,其中有著“內容+屬性”,這不就是一種抽象的“文件”嗎這些個文件提供統一的文件操作接口(write、read、open、close等),無論操作對象是鍵盤、鼠標還是其他什么硬件,用戶都可以通過相同的接口與之交互。

將上述思想和方法發散到其他系統資源,同樣通過“先整理,再管理”的思想,這或許是理解“Linux下一切皆文件”的思路之一吧。

問:磁盤等硬件有輸入輸出好理解,那如顯示器等硬件不是只有輸入或者只有輸出嗎?

答:雖然如顯示器等設備沒有輸入操作,我們只需將其struct內部的函數指針置為NULL即可。

以上是筆者目前對“Linux下一切皆文件”的理解,若筆者有錯誤的認識或者讀者有更深的理解,還請讀者不吝賜教,在評論區中一起討論。

二、緩沖區

1.緩沖區介紹

1)什么是緩沖區

緩沖區本質上就是一段內存。

2)為什么要有緩沖區

磁盤等存儲設備物理I/O效率極低,通過引入緩沖區將多次小數據操作合并為大數據操作,從而節省數據IO時間,提升性能。

2.緩沖區的刷新策略

通過以下代碼觀察緩沖區:

在程序sleep的十秒之間printf不會打印,等sleep結束后才會打印。

注意printf沒有帶\n。

  1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("hello Linux");//注意沒帶\n6     sleep(10);                                                                                                                                           7     return 0;8 }

但在printf和sleep之間添加了fflsh(stdout)后,printf會立即打印。

下面是緩沖區的三種刷新策略。

1)立即刷新——無緩沖

2)行刷新——行緩沖

3)緩沖區滿——全緩沖(效率最高)

有兩種特殊情況緩沖區會立即刷新:

①用戶強制刷新(如上述的fflush函數);

②程序退出——這也是為什么在某些集成開發環境下(如vs2022)程序時得等一會才能在控制臺上看到打印結果。

3.用戶級緩沖區

引子——觀察下列代碼在bash不同指令下的執行情況:

  1 #include<stdio.h>2 #include<unistd.h>3 #include<string.h>4 int main()5 {6     printf("hello Linux\n");//注意沒帶\n7     fprintf(stdout,"hello fprintf\n");8     fputs("hello fpurs",stdout);9     const char *str="hello writie\n";10     write(stdout->_fileno,str,strlen(str));11 12     fork();                                                                                                                                              13     return 0;14 }

執行 .?/ test:

執行. / test > log.txt

可以發現. / test > log.txt比. / test多打印了幾行,這多打印的全是C標準庫提供的函數。

這個用戶級緩沖區在哪呢?

通過觀察stdout的類型,我們可以推導出FILE中不僅有文件描述符,還存在緩沖區,所有當我們想要主動刷新緩沖區時,fflush傳入的是FILE*指針。

解釋關于fork再加重定向“>”后數據會打印兩份的原因

①沒有進行>時,我們看到打印了四條數據。stdout默認采用的是行刷新,在進行fork之前三條C函數已經將數據打印到顯示器上了,FILE中不在存有相應數據了;

如果我們進行了>,寫入的文件不再是顯示器,而是普通文件,采用的刷新策略也不再是行緩沖而是全緩沖,而這三條C打印顯然不能填滿緩沖區,于是數據就沒有被刷新。fork函數之后緊接著就是程序退出,故當fork創建子進程后,無論父子進程誰先退出都必定會發生寫時拷貝(緩沖區刷新就是修改),因此父子進程分別向log.txt中打印了數據。

至于write,他是linux系統調用,不屬于C,且write用的是fd文件描述符沒有使用FILE結構體,所以C提供的緩沖區中就不考慮write,因此無論那種情況write都只打印了一次。

為什么stdout標準輸出默認采用行緩沖?

有關文件描述符的解釋,參看:Linux中有關文件操作的系統接口,文件描述符,重定向的介紹-CSDN博客

有關fork函數和寫時拷貝的解釋,參看:

Linux環境下的進程創建-fork函數的使用與寫時拷貝, 進程退出exit和_exit的區別,以及進程等待waitpid和status數據的提取方法-CSDN博客

4.內核緩沖區簡介

1)內核緩沖區在相應文件的file_struct中。流是文件的特殊或者說流是文件的一種高級抽象。

file_struct與task_struct(PCB)一樣都是內核級數據結構,在task_struct中有著指向file_struct的指針。

2)內核緩沖區的刷新策略完全由OS自主決定;

3)完整的數據刷新過程:

4)fsync函數:強制將內核緩沖區中的數據刷入磁盤。


總結

筆者水平淺薄,對于上述內容難免有疏忽疑錯,還請讀者多多指處。

希望本文對你有所幫助

讀完點贊,手留余香~

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

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

相關文章

車道線檢測----CLRERNet

CLRerNet&#xff1a;利用LaneIoU提升車道檢測置信度 摘要 車道標檢測在自動駕駛和駕駛輔助系統中至關重要。現代深度車道檢測方法在車道檢測基準測試中表現出色。通過初步的預言機實驗&#xff0c;我們首次拆解車道表示組件以確定研究方向。我們表明&#xff0c;正確的車道位…

ML307R 的 USB Vendor ID (VID):0x2ECC ML307R 的 USB Product ID (PID):0x3012

可以的&#xff0c;在文檔的「Table 3. VID、PID查詢表」中明確指出&#xff1a; ML307R 的 USB Vendor ID (VID)&#xff1a;0x2ECCML307R 的 USB Product ID (PID)&#xff1a;0x3012 你可以將這對 VID/PID 加到 Linux 的 option 驅動中&#xff0c;比如&#xff1a; ech…

論信息系統項目的范圍管理

論信息系統項目的范圍管理 前言一、規劃范圍管理&#xff0c;收集需求二、定義范圍三、創建工作分解結構四、確認范圍五、控制范圍 前言 為了應對煙草零售客戶數量大幅度增長所帶來的問題&#xff0c;切實履行控煙履約的相關要求&#xff0c;同時也為了響應國務院“放管服”政策…

MongoDB與PostgreSQL兩個數據庫的特點詳細對比

MongoDB 和 PostgreSQL 是兩種不同類型的數據庫&#xff0c;分別屬于 ??NoSQL&#xff08;文檔型&#xff09;?? 和 ??關系型&#xff08;SQL&#xff09;?? 數據庫。它們在數據模型、查詢語言、擴展性、事務支持等方面有顯著差異。以下是詳細對比&#xff1a; ??1. …

計算機網絡:什么是電磁波以及有什么危害?

電磁波詳解 電磁波(Electromagnetic Wave)是由電場和磁場相互激發、在空間中傳播的能量形式。它既是現代通信的基石(如手機、Wi-Fi、衛星信號),也是自然界中光、熱輻射等現象的本質。以下從定義、產生、特性、分類及應用全面解析: 一、電磁波的本質 1. 核心定義 電場與…

如何使用 Solana Yellowstone gRPC 重新連接和重放插槽

Yellowstone gRPC 是一個功能強大、可用于生產環境且經過實戰檢驗的工具&#xff0c;用于流式傳輸實時的 Solana 數據。但在實際條件下&#xff0c;網絡中斷或服務器重啟可能導致連接中斷。如果沒有適當的重連策略&#xff0c;你的應用程序可能會錯過區塊鏈的關鍵更新。 為了防…

foxmail - foxmail 啟用超大附件提示密碼與帳號不匹配

foxmail 啟用超大附件提示密碼與帳號不匹配 問題描述 在 foxmail 客戶端中&#xff0c;啟用超大附件功能&#xff0c;輸入了正確的賬號&#xff08;郵箱&#xff09;與密碼&#xff0c;但是提示密碼與帳號不匹配 處理策略 找到 foxmail 客戶端目錄/Global 目錄下的 domain.i…

MySQL 事務(一)

文章目錄 CURD不加控制&#xff0c;會有什么問題CURD滿足什么屬性&#xff0c;能解決上述問題&#xff1f;什么是事務為什么要有事務事務的版本支持了解事務的提交方式 事務常見操作方式研究并發場景事務的正常操作事務的非正常情況的案例結論事務操作的注意事項 CURD不加控制&…

CSS面試題匯總

在前端開發領域&#xff0c;CSS 是一項不可或缺的技術。無論是頁面布局、樣式設計還是動畫效果&#xff0c;CSS 都扮演著重要的角色。因此&#xff0c;在前端面試中&#xff0c;CSS 相關的知識點往往是面試官重點考察的內容。為了幫助大家更好地準備面試&#xff0c;本文匯總了…

Java 后端給前端傳Long值,精度丟失的問題與解決

為什么后端 Long 類型 ID 要轉為 String&#xff1f; 在前后端分離的開發中&#xff0c;Java 后端通常使用 Long 類型作為主鍵 ID&#xff08;如雪花算法生成的 ID&#xff09;。但如果直接將 Long 返回給前端&#xff0c;可能會導致前端精度丟失的問題&#xff0c;特別是在 J…

對稱二叉樹的判定:雙端隊列的精妙應用

一、題目解析 題目描述 給定一個二叉樹&#xff0c;檢查它是否是鏡像對稱的。例如&#xff0c;二叉樹 [1,2,2,3,4,4,3] 是對稱的&#xff1a; 1/ \2 2/ \ / \ 3 4 4 3而 [1,2,2,null,3,null,3] 則不是鏡像對稱的&#xff1a; 1/ \2 2\ \3 3問題本質 判斷一棵二叉…

C#數組與集合

&#x1f9e0; 一、數組&#xff08;Array&#xff09; 1. 定義和初始化數組 // 定義并初始化數組 int[] numbers new int[5]; // 默認值為 0// 聲明并賦值 string[] names { "Tom", "Jerry", "Bob" };// 使用 new 初始化 double[] scores …

本地部署Scratch在線編輯器

1、說明 由于在GitHub上沒有找到Scratch源碼&#xff0c;所以只能編寫腳本下載官網相關資源&#xff0c;然后在本地部署。 如果你找到了Scratch源碼&#xff0c;請自行編譯部署&#xff0c;可忽略以下操作。 項目結構&#xff1a;scratch.mit.edu |-- chunks | |-- fetch-w…

Gmsh 讀取自定義輪廓并劃分網格:深入解析與實踐指南

一、Gmsh 簡介 (一)Gmsh 是什么 Gmsh 是一款功能強大的開源有限元網格生成器,廣泛應用于工程仿真、數值模擬以及計算機圖形學等領域。它為用戶提供了從幾何建模到網格劃分的一整套解決方案,能夠有效處理復雜幾何形狀,生成高質量的二維和三維網格,滿足多種數值方法的需求…

Elabscience 精準識別 CD4+ T 細胞|大鼠源單克隆抗體 GK1.5,適配小鼠樣本的流式優選方案

內容概要 CD4 T細胞在免疫調節、自身免疫疾病及腫瘤免疫治療中發揮關鍵作用。Elabscience推出的APC Anti-Mouse CD4 Antibody (GK1.5)&#xff08;貨號&#xff1a;E-AB-F1097E&#xff09;是一款高特異性、低背景的流式抗體&#xff0c;專為小鼠CD4 T細胞亞群檢測優化設計。該…

【RabbitMQ】應用問題、仲裁隊列(Raft算法)和HAProxy負載均衡

&#x1f525;個人主頁&#xff1a; 中草藥 &#x1f525;專欄&#xff1a;【中間件】企業級中間件剖析 一、冪等性保障 什么是冪等性&#xff1f; 冪等性是指對一個系統進行重復調用&#xff08;相同參數&#xff09;&#xff0c;無論同一操作執行多少次&#xff0c;這些請求…

51 單片機頭文件 reg51.h 和 reg52.h 詳解

51 單片機頭文件詳解 51 單片機的頭文件reg51.h和reg52.h是開發中非常重要的文件,它們定義了單片機的特殊功能寄存器 (SFR) 和位地址。以下是對這兩個頭文件的詳細解析: 1. 頭文件概述 reg51.h:針對標準 8051 單片機(4KB ROM, 128B RAM) reg52.h:針對增強型 8052 單片…

前端的面試筆記——JavaScript篇(二)

一、instanceof 在 JavaScript 里&#xff0c;instanceof 是一個相當實用的運算符&#xff0c;它的主要功能是檢查某個對象是否屬于特定構造函數的實例。這里需要明確的是&#xff0c;判斷的依據并非對象的類型&#xff0c;而是其原型鏈。下面為你詳細介紹它的用法和特點&…

”一維前綴和“算法原理及模板

前綴和&#xff0c;就是通過一種方法來求出數組中某個連續區間的元素的和的辦法。我們通常先預處理出來一個前綴和數組&#xff0c;然后把數組中進行元素填充后再進行后續使用。 我們通過一道模板題或許能更加理解其意思。 現在的問題就是&#xff1a;如果我們用暴力枚舉來記錄…

5.13/14 linux安裝centos及一些操作命令隨記

一、環境準備 VMware Workstation版本選擇建議 CentOS 7 ISO鏡像下載指引 虛擬機硬件配置建議&#xff08;內存/處理器/磁盤空間&#xff09; 二、系統基礎命令 一、環境準備 1.VMware Workstation版本選擇建議 版本選擇依據 選擇VMware Workstation的版本時&#xff0c…