欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux中的緩沖區(qū)和文件系統(tǒng)詳解

 更新時(shí)間:2025年03月20日 14:29:04   作者:s_little_monster_  
這篇文章主要介紹了Linux中的緩沖區(qū)和文件系統(tǒng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、FILE結(jié)構(gòu)

1、fd

FILE是在C中封裝起來(lái)的一個(gè)結(jié)構(gòu)體,那我們?cè)L問(wèn)文件的時(shí)候都是通過(guò)fd訪(fǎng)問(wèn)的,自然在FILE中是封裝了fd的,F(xiàn)ILE結(jié)構(gòu)體中,int _file存放的就是fd,其他的成員基本都是與緩沖區(qū)有關(guān)的

2、緩沖區(qū)

(一)有換行有return全部打印

看下面一段代碼:

(二)無(wú)換行無(wú)return的C接口打印

很顯然的,我們打印出了所有我們需要的內(nèi)容,我們?cè)倏聪乱欢?/p>

理想狀態(tài)下我們應(yīng)該是打印出結(jié)果后然后進(jìn)行while一直循環(huán),實(shí)際上是一只不會(huì)打印,這是為什么呢?是的,待在緩沖區(qū)里

首先我們要知道,緩沖區(qū)的大概位置,我們上面貼了一張F(tuán)ILE結(jié)構(gòu)體的結(jié)構(gòu)圖,我們可以很清楚地看到緩沖區(qū)是FILE的成員指針指向的一塊位置,也就是說(shuō)緩沖區(qū)一定在用戶(hù)空間而不是內(nèi)核空間

(三)無(wú)換行無(wú)return的系統(tǒng)調(diào)用接口打印

我們?cè)谡{(diào)用上面三個(gè)函數(shù)的時(shí)候,都是調(diào)用的C接口,自然都待在緩沖區(qū)里了,我們?cè)倏聪乱粋€(gè)程序

在這個(gè)程序中我們直接調(diào)用系統(tǒng)調(diào)用接口write,所以它不會(huì)經(jīng)過(guò)C語(yǔ)言的緩沖區(qū),而是直接打印

(四)有換行無(wú)return的C接口打印

我們?cè)賮?lái)看一組程序

這個(gè)程序和(二)程序的區(qū)別就只有換行,這告訴我們,C語(yǔ)言緩沖區(qū)對(duì)于顯式器是行緩沖的,C語(yǔ)言標(biāo)準(zhǔn)庫(kù)的文件流有三種緩沖模式,分別是全緩沖、行緩沖和無(wú)緩沖

  • 全緩沖 _IOFBF :通常用于對(duì)磁盤(pán)文件的操作,數(shù)據(jù)會(huì)先被存儲(chǔ)在緩沖區(qū)中,直到緩沖區(qū)被填滿(mǎn)或者調(diào)用 fflush 函數(shù)、關(guān)閉文件(fclose)時(shí),才會(huì)將緩沖區(qū)中的數(shù)據(jù)寫(xiě)入實(shí)際的文件,在全緩沖模式下,不會(huì)因?yàn)橛龅綋Q行符而自動(dòng)刷新緩沖區(qū)
  • 行緩沖 _IOLBF :常見(jiàn)于標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出等終端設(shè)備相關(guān)的流,當(dāng)遇到換行符(\n)時(shí),會(huì)自動(dòng)刷新緩沖區(qū),將緩沖區(qū)中的數(shù)據(jù)寫(xiě)入對(duì)應(yīng)的設(shè)備或文件,某些情況下即使沒(méi)有換行符,緩沖區(qū)滿(mǎn)時(shí)也會(huì)刷新
  • 無(wú)緩沖 _IONBF :標(biāo)準(zhǔn)錯(cuò)誤輸出通常默認(rèn)是無(wú)緩沖的,確保錯(cuò)誤信息能夠立即顯示,在無(wú)緩沖模式下,數(shù)據(jù)會(huì)立即寫(xiě)入對(duì)應(yīng)的設(shè)備或文件,不會(huì)進(jìn)行緩沖,因此不存在行刷新的概念

(五)無(wú)換行有return的C接口打印

進(jìn)程退出return的時(shí)候,也會(huì)對(duì)緩沖區(qū)進(jìn)行刷新

(六)深入理解緩沖區(qū)在用戶(hù)空間

我們打印在顯示器上的內(nèi)容和打印在文件中的內(nèi)容不一致,只有write打印了一遍,其他是按照順序打印了兩遍,我們當(dāng)然能看出來(lái)這是fork的鍋,接下來(lái)我們就深入理解談一談緩沖區(qū)

首先我們分析第一張結(jié)果圖,因?yàn)轱@示器是行緩沖的,所以我們C接口的打印放到緩沖區(qū)中一行就會(huì)被打印到屏幕上一行,三條語(yǔ)句執(zhí)行完之后緩沖區(qū)是空的,然后write再往上寫(xiě),所以整個(gè)打印出來(lái)的順序也是按照代碼中來(lái)的

然后我們分析最后一張圖,第一個(gè)我們可以肯定的是,打印到文件一定不是行緩沖,那就更不是無(wú)緩沖,實(shí)際上,由于文件是在存儲(chǔ)硬件當(dāng)中的,由于我們的效率問(wèn)題,對(duì)于這種存儲(chǔ)類(lèi)的緩沖條件都是全緩沖,把緩沖區(qū)塞滿(mǎn)再寫(xiě)入存儲(chǔ)硬件中比塞一點(diǎn)寫(xiě)一點(diǎn)效率高得多,所以前三句C接口調(diào)用的打印全部在緩沖區(qū)中,然后write將自己打印,然后我們就碰到了fork,創(chuàng)建子進(jìn)程,父子進(jìn)程此時(shí)共享代碼段和數(shù)據(jù)段,因?yàn)樗鼈兌紱](méi)有做修改,然后我們就碰到了return 0,前面我們提到:進(jìn)程結(jié)束也是要清空緩沖區(qū)的,此時(shí)父或子進(jìn)程某一個(gè)先結(jié)束(由調(diào)度器決定),其中一個(gè)進(jìn)程清空緩沖區(qū)的行為會(huì)引起另一個(gè)進(jìn)程的寫(xiě)實(shí)拷貝,此時(shí)我們就有兩份緩沖區(qū),兩個(gè)進(jìn)程都結(jié)束都要清空緩沖區(qū),自然在緩沖區(qū)中的內(nèi)容要打印兩份了(在這里要注意了,不只是子進(jìn)程修改數(shù)據(jù)會(huì)引起子進(jìn)程的寫(xiě)時(shí)拷貝,父進(jìn)程對(duì)數(shù)據(jù)做修改時(shí)父進(jìn)程也要發(fā)生寫(xiě)時(shí)拷貝,被寫(xiě)時(shí)拷貝的數(shù)據(jù)再再發(fā)生修改就直接修改了,不發(fā)生寫(xiě)實(shí)拷貝

二、文件系統(tǒng)

文件一般存儲(chǔ)在硬盤(pán)當(dāng)中,我們已經(jīng)學(xué)習(xí)了動(dòng)態(tài)的文件,也就是進(jìn)程打開(kāi)文件訪(fǎng)問(wèn)文件的過(guò)程,現(xiàn)在我們來(lái)學(xué)習(xí)一下靜態(tài)的文件,我們來(lái)直接學(xué)習(xí)一下固態(tài)硬盤(pán)

1、固態(tài)硬盤(pán)

固態(tài)硬盤(pán)是一種基于NAND閃存的存儲(chǔ)單元,我們常用的筆記本上的固態(tài)硬盤(pán)存儲(chǔ)單元類(lèi)型一般都是TLC的,三層單元,每個(gè)單元存儲(chǔ)3bits,壽命較短成本較低,它通過(guò)電荷存儲(chǔ)數(shù)據(jù),通過(guò)高低電平區(qū)分0/1

NAND閃存的寫(xiě)入操作只能在已擦除的塊上進(jìn)行,擦除的最小單位就是塊,通常為128KB-4MB,寫(xiě)入的最小單位是頁(yè),通常為4KB,所以它讀的速度特別快,可以到微秒級(jí),因?yàn)樾枰炔脸龎K,寫(xiě)的速度較慢,只能到毫秒級(jí),每個(gè)塊的擦寫(xiě)次數(shù)有限,超過(guò)后就會(huì)失效,一般TLC的擦鞋上限在500-1500次

這樣的性質(zhì)會(huì)帶來(lái)一些不太好的結(jié)果,比如我們要寫(xiě)的內(nèi)容很小,假設(shè)為4KB,那么我們先要擦除高達(dá)4MB的塊才能進(jìn)行寫(xiě)入,所以我們通過(guò)算法,將寫(xiě)入分散到所有塊,避免某些塊因?yàn)槎啻尾脸?/p>

固態(tài)硬盤(pán)控制器中的核心邏輯叫做FTL ( Flash Translation Layer ) Flash翻譯層,負(fù)責(zé)將文件系統(tǒng)的邏輯地址映射到物理地址,是不是有點(diǎn)像進(jìn)程地址通過(guò)頁(yè)表映射到物理地址呢

接下來(lái)我們要學(xué)習(xí)文件系統(tǒng)的邏輯地址LBA,因?yàn)槲覀兒芮宄﨔TL映射到物理地址的過(guò)程是與頁(yè)表映射是相似的,而邏輯地址的組織方式與進(jìn)程地址可是不同的,雖然是有相似之處的~

2、邏輯地址LBA

LBA 從 0 開(kāi)始,按照連續(xù)的整數(shù)順序依次為存儲(chǔ)設(shè)備中的每個(gè)數(shù)據(jù)塊編號(hào),存儲(chǔ)設(shè)備中的每個(gè)數(shù)據(jù)塊都對(duì)應(yīng)一個(gè)唯一的 LBA 值,比如第一個(gè)數(shù)據(jù)塊的 LBA 是 0,第二個(gè)是 1,依此類(lèi)推,我們對(duì)應(yīng)的數(shù)據(jù)塊有Super Block、Group Descriptor Table、Block Bitmap、inode Bitmap、inode Table、Data blocks六個(gè),最理想的情況下它們的LBA按照我上面寫(xiě)的順序從0到5

我們把一塊固態(tài)硬盤(pán),我們筆記本上有一些品牌比如說(shuō)某L開(kāi)頭的品牌,在我們購(gòu)買(mǎi)的時(shí)候是默認(rèn)給你帶1T固態(tài)的,一般的品牌就是512G,我們拿到筆記本之后會(huì)對(duì)電腦進(jìn)行分區(qū),C盤(pán)作為系統(tǒng)盤(pán)分到最多的內(nèi)存,G盤(pán)作為游戲盤(pán)給到300多G,然后D盤(pán)用來(lái)學(xué)習(xí)寫(xiě)代碼,留個(gè)200G,EF盤(pán)用來(lái)存一些其他的東西,這樣一套流程下來(lái)我們就分好盤(pán)了,我們說(shuō)對(duì)硬盤(pán)做管理當(dāng)然也是先描述后組織,Block Group就是組織和管理磁盤(pán)空間的一種重要結(jié)構(gòu)

在n個(gè)Block Group之前有一個(gè)叫做Boot Block(引導(dǎo)塊)的區(qū)域,在計(jì)算機(jī)啟動(dòng)過(guò)程中起著至關(guān)重要的作用,它是計(jì)算機(jī)啟動(dòng)過(guò)程的起點(diǎn),沒(méi)有引導(dǎo)塊中的引導(dǎo)代碼,計(jì)算機(jī)就無(wú)法知道如何加載操作系統(tǒng),也就無(wú)法正常啟動(dòng)

我們按照知識(shí)理解易難順序倒著往前來(lái)說(shuō)

(一)數(shù)據(jù)塊 Data Blocks

用來(lái)存儲(chǔ)數(shù)據(jù)的塊,NAND FLASH 內(nèi)部的數(shù)據(jù)塊由多個(gè)page組成,通常大小為4KB(現(xiàn)在也有8KB和16KB),這個(gè)page就是我們前面提到的最小寫(xiě)入單位:頁(yè)

(二)inode表 inode Table

inode全稱(chēng)為索引節(jié)點(diǎn),是一種數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)單個(gè)文件的全部屬性,一般來(lái)說(shuō)每個(gè)文件都有一個(gè)inode

struct inode
{
	//inode編號(hào)
	//文件類(lèi)型
	//權(quán)限
	//引用計(jì)數(shù)
	//擁有者
	//所屬組
	
    // 直接塊指針
    unsigned long i_block[NUM];
    // 一次間接塊指針
    unsigned long i_ind_block;
    // 二次間接塊指針
    unsigned long i_dind_block;
    // 三次間接塊指針
    unsigned long i_tind_block;
}

其中inode編號(hào)每個(gè)文件都是不同的,我們主要說(shuō)說(shuō)數(shù)據(jù)塊指針

(1)直接塊指針

直接塊指針的NUM一般是12,它指向的位置是我們可以直接用來(lái)存儲(chǔ)的位置,如果我們內(nèi)容比較?。?code>12*4KB = 48KB以?xún)?nèi)),那么直接塊指針可以直接訪(fǎng)問(wèn)這些數(shù)據(jù)

(2)一次間接塊指針

如果內(nèi)容大于48KB,就需要一次間接塊指針,一次間接塊指針指向一個(gè)間接塊,這個(gè)間接塊存儲(chǔ)中存儲(chǔ)著多個(gè)指向數(shù)據(jù)塊的指針,如我們的內(nèi)容在(4KB/4b)*4KB = 4MB以?xún)?nèi),通過(guò)一次間接塊指針和直接塊指針就可以訪(fǎng)問(wèn)這些數(shù)據(jù)

(3)二次間接塊指針

二次間接塊指針指向一個(gè)二次間接塊,這個(gè)二次間接塊存儲(chǔ)中存儲(chǔ)著多個(gè)指向間接塊的指針,與一次間接塊指針類(lèi)似,這樣我們存儲(chǔ)的范圍就達(dá)到了(4KB/4b)*(4KB/4b)*4KB = 4GB

(4)三次間接塊指針

同上,最終我們最大的存儲(chǔ)范圍達(dá)到了 (4KB/4b)*(4KB/4b)*(4KB/4b)*4KB = 4TB

(三)inode位圖 inode Bitmap

我們通過(guò)位圖來(lái)和inode一一對(duì)應(yīng),位圖上對(duì)應(yīng)的比特位為0,那么該inode就沒(méi)有被使用,可以被分配,如果為1則被占用,當(dāng)從1變?yōu)?時(shí),該inode又可以被分配了,其實(shí)這個(gè)過(guò)程就是一個(gè)刪除的過(guò)程,一旦一個(gè)文件的inode無(wú)了,那么這文件是真的無(wú)了

在文件系統(tǒng)中,標(biāo)識(shí)文件不是看它的名字,而是看它的inode,一旦inode和文件取消綁定了,那么操作系統(tǒng)就找不到這個(gè)文件了,再次寫(xiě)入其他內(nèi)容的時(shí)候也就會(huì)被擦除覆蓋了,換而言之,刪除恒等于可以被覆蓋

(四)塊位圖 Block Bitmap

我們通過(guò)位圖來(lái)和數(shù)據(jù)塊page一一對(duì)應(yīng),位圖上對(duì)應(yīng)的比特位為0,那么該頁(yè)page就沒(méi)有被使用,可以被分配,如果為1則被占用,當(dāng)從1變?yōu)?時(shí),該page又可以被分配了,如果我們要?jiǎng)h除一塊空間,只需要將它的對(duì)應(yīng)的位置0,到再次被寫(xiě)入的時(shí)候就會(huì)消失了,當(dāng)然我們的NAND閃存是定期擦除的,過(guò)一段時(shí)間它自己就被擦除了

(五)塊組描述符表 Group Descriptor Table

記錄了該塊組的詳細(xì)信息,包括塊位圖的位置、inode 位圖的位置、inode 表的起始位置等,用于定位和管理塊組內(nèi)的各種數(shù)據(jù)結(jié)構(gòu)

(六)超級(jí)塊 Super Block

超級(jí)塊是文件系統(tǒng)的核心,記錄了文件系統(tǒng)的全局信息,如塊大小、inode 數(shù)量、空閑塊數(shù)量等,為了防止超級(jí)塊損壞導(dǎo)致文件系統(tǒng)無(wú)法使用,每個(gè)塊組中可能會(huì)包含超級(jí)塊的副本,不過(guò)并非所有塊組都有

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Linux系統(tǒng)刪除文件夾和文件的命令

    Linux系統(tǒng)刪除文件夾和文件的命令

    筆者給大家介紹Linux系統(tǒng)刪除文件夾和文件的命令,很多朋友喜歡是rmdir命令來(lái)刪除文件,不過(guò)當(dāng)遇到目錄非空,就會(huì)麻煩,下面閱讀本文學(xué)習(xí)下linux刪除文件夾和文件的命令吧
    2018-02-02
  • .htaccess rewrite 規(guī)則詳細(xì)說(shuō)明

    .htaccess rewrite 規(guī)則詳細(xì)說(shuō)明

    用Apache虛擬主機(jī)的朋友很多,apache提供的.htaccess模塊可以為每個(gè)虛擬主機(jī)設(shè)定rewrite規(guī)則,這對(duì)網(wǎng)站SEO優(yōu)化相當(dāng)有用,同時(shí)也改善了用戶(hù)體驗(yàn)
    2016-04-04
  • 解決因文件權(quán)限導(dǎo)致git fetch命令執(zhí)行失敗的問(wèn)題

    解決因文件權(quán)限導(dǎo)致git fetch命令執(zhí)行失敗的問(wèn)題

    最近在工作中遇到一個(gè)問(wèn)題,就是在在一個(gè)基于 git 的發(fā)布系統(tǒng)中拉取代碼,發(fā)現(xiàn)無(wú)法拉取最新的提交記錄,查找相關(guān)資料發(fā)現(xiàn)是因?yàn)槲募?quán)限的問(wèn)題,所以這篇文章主要介紹了關(guān)于解決因文件權(quán)限導(dǎo)致git fetch命令執(zhí)行失敗的問(wèn)題,需要的朋友可以參考下。
    2017-04-04
  • Linux watch命令的使用

    Linux watch命令的使用

    這篇文章主要介紹了Linux watch命令的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Linux系統(tǒng)重啟后MySQL數(shù)據(jù)丟失問(wèn)題的解決步驟

    Linux系統(tǒng)重啟后MySQL數(shù)據(jù)丟失問(wèn)題的解決步驟

    今天分享一個(gè)在Linux系統(tǒng)中經(jīng)常遇到的問(wèn)題:系統(tǒng)重啟后發(fā)現(xiàn)MySQL無(wú)法啟動(dòng),而且數(shù)據(jù)似乎丟失了,這個(gè)問(wèn)題可能會(huì)讓人驚慌失措,但別擔(dān)心,通常情況下這只是因?yàn)閿?shù)據(jù)盤(pán)沒(méi)有正確掛載導(dǎo)致的,現(xiàn)在我們將深入探討這個(gè)問(wèn)題的原因、解決方法以及如何預(yù)防它的再次發(fā)生
    2024-09-09
  • Linux修改pip和conda緩存路徑的幾種方法

    Linux修改pip和conda緩存路徑的幾種方法

    在 Python 生態(tài)中,pip 和 conda 是兩種常見(jiàn)的軟件包管理工具,它們?cè)诎惭b、更新和卸載軟件包時(shí)都會(huì)使用緩存來(lái)提高效率,適當(dāng)?shù)匦薷乃鼈兊木彺媛窂?不僅可以?xún)?yōu)化存儲(chǔ)管理,還可以在存儲(chǔ)空間有限,本文將詳細(xì)介紹如何修改 pip 和 conda 的緩存路徑
    2025-03-03
  • Linux下查看IP地址不顯示解決辦法

    Linux下查看IP地址不顯示解決辦法

    大家好,本篇文章主要講的是Linux下查看IP地址不顯示解決辦法,感興趣的同學(xué)趕快來(lái)看看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽
    2021-12-12
  • 詳解CentOS7 安裝 MariaDB 10.2.4的方法

    詳解CentOS7 安裝 MariaDB 10.2.4的方法

    這篇文章主要介紹了CentOS7 安裝 MariaDB 10.2.4的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • ubuntu服務(wù)器上快速部署docker的方法

    ubuntu服務(wù)器上快速部署docker的方法

    本篇文章主要介紹了ubuntu服務(wù)器上快速部署docker的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-07-07
  • Linux基本網(wǎng)絡(luò)配置方法介紹

    Linux基本網(wǎng)絡(luò)配置方法介紹

    本篇文章主要介紹了Linux網(wǎng)絡(luò)基本網(wǎng)絡(luò)配置方法介紹,對(duì)于初學(xué)linux有一定的幫助,有需要的朋友可以了解一下。
    2016-12-12

最新評(píng)論