深入了解linux系統—— 操作系統的路徑緩沖與鏈接機制

前言

在之前學習當中,我們了解了被打開的文件是如何管理的;磁盤,以及ext2文件系統是如何存儲文件的。

那我們要打開一個文件,首先要先找到這個文件,操作系統又是如何去查找的呢?

理解操作系統搜索文件

1. 目錄和文件名

我們知道:

  • 文件名是不作為文件屬性存儲在文件inode里的;
  • 在一個分區中,根據文件的inode值就可以找到該文件。

但是在之前的文件操作時,一種都是使用文件名進行對文件的相關操作,沒有使用過文件inode值;

還用目錄它是文件嗎?

在這里插入圖片描述

通過查看我們可以發現目錄也是存在inode值的,那也就是說目錄也是也文件;

文件 = 屬性 + 內容,那目錄的文件內容是什么呢?

首先屬性不用多說;

目錄文件的文件內容保存的是:文件名和inode號的映射關系。

  • 所以,訪問文件時,必須打開當前工作目錄,根據文件名獲取對應的inode號,然后進行文件訪問。
  • 所以,訪問文件必須知道當前工作目錄,本質就是必須打開當前工作目錄文件,查看目錄文件的內容獲取要訪問文件的inode號。

2. 路徑解析

知道了訪問當前工作目錄下文件,要打開當前目錄文件,查看當前目錄文件內容;

那要打開當前工作目錄,就要獲取當前工作目錄文件的inode號啊,如何獲得呢?

很簡單,打開上級目錄,查看上級目錄文件內容;那上級目錄也是文件啊,要打開它也要知道它的inode號,那也要打開它的上級目錄啊?

所以就一直訪問上級目錄,直到/根目錄。

所以說:實際上,任何文件都存在路徑;

比如:/home/lxb/linux/lesson8/code.c

這都要從根目錄開始一次打開每一個目錄文件,依次訪問每個目錄下的指定目錄直到test.c文件(這個過程稱之為Linux路徑解析)

我們知道,訪問文件本質就是進程去訪問,在進程當中存在CWD當前工作路徑;在我們open打卡指定文件時也給定了文件的路徑。

所以我們訪問文件必須要有目錄+文件名(絕對路徑)

3. 路徑緩存

我們知道,文件都是在磁盤中存著的,那在Linux系統中存在真正的目錄嗎?

顯而易見是不存在,只有文件;保存文件屬性+內容。

在上述中,我們還了解到訪問一個文件,都要從根目錄/開始進行路徑解析?

按道理來說是的,但是太慢了,在Linux系統中會緩沖歷史路徑結構。

Linux系統中,不存在目錄,那在Linux系統中我們為什么可以看到目錄路徑結構?

打開的文件如果是目錄,在系統中就在自己的內存中進行路徑維護。

Linux系統中,內核里維護樹狀路徑結構的內核結構體叫做:struct dentry

struct dentry {atomic_t d_count;unsigned int d_flags; /* protected by d_lock */spinlock_t d_lock; /* per dentry lock */struct inode *d_inode; /* Where the name belongs to - NULL is* negative *//*The next three fields are touched by __d_lookup. Place them hereso they all fit in a cache line.*/struct hlist_node d_hash; /* lookup hash list */struct dentry *d_parent; /* parent directory */struct qstr d_name;struct list_head d_lru; /* LRU list *//*d_child and d_rcu can share memory*/union {struct list_head d_child; /* child of parent list */struct rcu_head d_rcu;} d_u;struct list_head d_subdirs; /* our children */struct list_head d_alias; /* inode alias list */unsigned long d_time; /* used by d_revalidate */struct dentry_operations *d_op;struct super_block *d_sb; /* The root of the dentry tree */void *d_fsdata; /* fs-specific data */
#ifdef CONFIG_PROFILINGstruct dcookie_struct *d_cookie; /* cookie, if any */
#endifint d_mounted;unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};
  • 每一個文件其實都有對應的dentry結構,包含普通文件;所以被打開的文件,在內存中就可以形成樹狀結構。
  • 整個樹形節點也會同時屬于LRU(Least Recently Used),在最近最少使用結構在,進行節點淘汰。
  • 同時也會屬于Hash表,方便快速查找。
  • 這樣有了樹狀結構,整體就有了Linux路徑緩存結構,打開和訪問任何文件,都先在該樹下進行查找,找到了就返回inode和內容,沒找到就從磁盤加載路徑,添加到dentry結構中。

4. 掛載分區

在之前的描述中,都是在一個文件系統中,根據inode號查找文件,那inode號又不是跨分區的,如何根據inode確定是哪一個分區呢?

在分區寫入文件系統后,我們沒有辦法直接使用;我們需要將文件系統與指定的目錄進行關聯(也就是掛載)才能使用

所以就可以根據我們訪問目標文件的路徑前綴來判斷文件在哪一個分區。

這里關于掛載的相關操作,就不演示了;可以自己嘗試一下。

軟硬鏈接

1. 軟鏈接

Windows中,我們可以給一個文件創建快捷方式,然后放到桌面,這樣打開桌面的快捷方式就是打開文件了;

而在Linux系統中,我們也可以給文件創建快捷方式——就是軟鏈接

ln -s code code.c

創建軟鏈接文件code指向文件code.c;(可以說code文件是code.c的快捷方式)

在這里插入圖片描述

軟鏈接是一個獨立的文件

2. 硬鏈接

我們直到一個目錄中,存在...兩個隱藏文件,.指向當前目錄,..指向上級目錄;

那也就是說,這些文件名都對應一個inode值。

這里...就是典型的硬鏈接。

而在內核中,記錄了連接數:

在這里插入圖片描述

創建硬鏈接:

ln 已存在文件 硬鏈接文件

在這里插入圖片描述

這里要注意,我們只能給文件創建硬鏈接,不能給目錄創建硬鏈接。

這里可能會感覺很奇怪,...不就是給目錄創建硬鏈接嗎?我們為什么不能創建?

這里還是為了避免循環路徑問題,在內核中在路徑搜索時,對...做了特殊處理,所以...不會造成循環路徑問題;

而軟鏈接,它是一個獨立的文件,在路徑遍歷時不會把他當做目錄文件來處理。

如果我們自己創建硬鏈接,就有可能造成循環路徑問題。

3. 軟硬鏈接的區別

  • 軟鏈接是一個獨立的文件
  • 硬鏈接只是文件名和目標文件的一組映射關系

4. 軟硬鏈接的作用

  • 軟鏈接就類似于快捷方式
  • 硬鏈接...,方便用戶進程操作;文件備份。

到這里本篇文章內容就結束了,感謝各位大佬的支持

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

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

相關文章

Docker Hub倉庫介紹

Docker Hub倉庫全解析:從公共市場到私有化部署指南 一、Docker Hub公共鏡像市場 1.1 核心功能解析 全球最大容器鏡像庫:累計托管超500萬鏡像核心服務矩陣: #mermaid-svg-CAMkhmtSWKEUw7z0 {font-family:"trebuchet ms",verdana,a…

redis使用RDB文件恢復數據

設置存盤間隔為120秒且10個key改變數據自動存盤使用RDB文件恢復數據 IP地址主機名192.168.10.170redis170 [rootredis170 ~]# yum install -y redis [rootredis170 ~]# systemctl start redis步驟一:設置存盤間隔為120秒且10個key改變自動存盤 [rootredis170 ~]#…

SpringBoot多環境配置文件切換

resources下application.yml、application-dev.yml、application-prod.yml多個配置文件。 spring:profiles:active: devspring:profiles:active: prod一般都是通過修改spring.profiles.active值來修改加載不同環境的配置信息,可以把切換的dev/prod放到pom.xml文件來…

Java 并發編程高級技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高級應用

Java 并發編程高級技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高級應用 一、引言 在 Java 并發編程中,CyclicBarrier、CountDownLatch 和 Semaphore 是三個常用且強大的并發工具類。它們在多線程場景下能夠幫助我們實現復雜的線程協調與資源控…

【Java多線程】多線程狀態下如何安全使用ArrayList以及哈希表

🔍 開發者資源導航 🔍🏷? 博客主頁: 個人主頁📚 專欄訂閱: JavaEE全棧專欄 多線程安全使用ArrayList 手動加鎖 日常中最常用的方法,使用synchronized進行加鎖,把代碼打包成一份&a…

InnoDB引擎底層解析(二)之InnoDB的Buffer Pool(三)

Buffer Pool 實例 我們上邊說過,Buffer Pool 本質是 InnoDB 向操作系統申請的一塊連續的內存空間,在多線程環境下,訪問 Buffer Pool 中的各種鏈表都需要加鎖處理,在Buffer Pool特別大而且多線程并發訪問特別高的情況下&#xff0…

Netty學習專欄(三):Netty重要組件詳解(Future、ByteBuf、Bootstrap)

文章目錄 前言一、Future & Promise:異步編程的救星1.1 傳統NIO的問題1.2 Netty的解決方案1.3 代碼示例:鏈式異步操作 二、ByteBuf:重新定義數據緩沖區2.1 傳統NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解決方案2.3 代碼示例:…

Vue3逐步拋棄虛擬Dom,React如何抉擇

虛擬DOM:前端界的替死鬼 這玩意兒就是個前端開發的充氣娃娃! 你以為它很牛逼?無非是給真DOM當替死鬼! 每次數據變,虛擬DOM先擱內存里自嗨一頓,diff算法跟便秘似的算半天,最后才敢碰真DOM。 說白…

分布式鎖總結

文章目錄 分布式鎖什么是分布式鎖?分布式鎖的實現方式基于數據庫(mysql)實現基于緩存(redis)多實例并發訪問問題演示項目代碼(使用redis)配置nginx.confjmeter壓測復現問題并發是1,即不產生并發問題并發30測試,產生并發問題(雖然單實例是synchronized&am…

解決自簽名證書HTTPS告警:強制使用SHA-256算法生成證書

解決自簽名證書HTTPS告警:強制使用SHA-256算法生成證書 一、問題場景 在使用OpenSSL生成和配置自簽名證書時,常遇到以下現象: 瀏覽器已正確導入根證書(.pem文件),但訪問HTTPS站點時仍提示不安全連接或證…

線上 Linux 環境 MySQL 磁盤 IO 高負載深度排查與性能優化實戰

目錄 一、線上告警 二、問題診斷 1. 系統層面排查 2. 數據庫層面分析 三、參數調優 1. sync_binlog 參數優化 2. innodb_flush_log_at_trx_commit 參數調整 四、其他優化建議 1. 日志文件位置調整 2. 生產環境核心參數配置模板 3. 突發 IO 高負載應急響應方案 五、…

window 顯示驅動開發-初始化和 DMA 緩沖區創建

若要指示 GPU 支持 GDI 硬件加速,顯示微型端口驅動程序的 DriverEntry 函數實現必須使用指向驅動程序實現的 DxgkDdiRenderKm 函數的指針填充 DRIVER_INITIALIZATION_DATA 結構的 DxgkDdiRenderKm 成員。 DirectX 圖形內核子系統調用 DxgkDdiRenderKm 函數&#xf…

Go語言實戰:使用 excelize 實現多層復雜Excel表頭導出教程

Go 實現支持多層復雜表頭的 Excel 導出工具 目錄 項目介紹依賴說明核心結構設計如何支持多層表頭完整使用示例總結與擴展 項目介紹 在實際業務系統中,Excel 文件導出是一項常見功能,尤其是報表類需求中常見的復雜多級表頭,常規表格組件往…

機器視覺6-halcon高級教程

機器視覺6-halcon高級教程 雙目立體視覺原理視差外極線幾何雙目標定 雙目立體視覺之Halcon標定一.標定結果二.Halcon標定過程1.獲取左右相機圖像中標定板的區域;2.提取左右相機圖像中標定板的MARK點坐標和攝像機外部參數;3.執行雙目標定;4.獲取非標準外極線幾何到標…

板凳-------Mysql cookbook學習 (六)

2025年Pytorch-gpu版本安裝(各種情況適用自己的安裝需求,親測絕對有效,示例安裝torch2.6.0,過程詳細面向小白)_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查錯 import s…

Spring boot和SSM項目對比

目錄對比 springboot目錄 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置類│ │ │ │ ├─controller // 存放控制器類│ │ │ │ ├─entity // 存…

《關于潯川社團退出DevPress社區及內容撤回的聲明》

《關于潯川社團退出DevPress社區及內容撤回的聲明》 尊敬的DevPress社區及讀者: 經潯川社團內部決議,我社決定自**2025年5月26日**起正式退出DevPress社區,并撤回所有由我社成員在該平臺發布的原創文章。相關事項聲明如下: …

Python性能優化利器:__slots__的深度解析與避坑指南

核心場景:當需要創建數百萬個屬性固定的對象時,默認的__dict__字典存儲會造成巨大內存浪費。此時__slots__能通過元組結構取代字典,顯著提升內存效率(實測節省58%內存)! 底層原理:為何能節省內…

Go 語言中的 Struct Tag 的用法詳解

在 Go 語言中,結構體字段標簽(Struct Tag) 是一種用于給字段添加元信息(metadata)的機制,常用于序列化(如 JSON、XML)、ORM 映射、驗證等場景。你在開發 Web 應用或處理數據交互時&a…

微軟正式發布 SQL Server 2025 公開預覽版,深度集成AI功能

微軟在今年的 Build 2025 大會上正式發布了 SQL Server 2025 公開預覽版,標志著這一經典數據庫產品在 AI 集成、安全性、性能及開發者工具方面的全面升級。 AI 深度集成與創新 原生向量搜索:SQL Server 2025 首次將 AI 功能直接嵌入數據庫引擎&#xff…