linux 中 fd 申請和釋放管理(兩級 bitmap)

linux 中 fd 的幾點理解_linux fd-CSDN博客

通過上邊的文章,我們可以知道,在 linux 中,fd 有以下幾點需要了解:

(1)fd 表示進程打開的文件,是進程級別的資源,不是系統級別的資源

(2)struct task_struct 在內核中用于描述一個進程,其中打開的文件使用 fd table 來描述

(3)在用戶態看 linux,一些皆文件

(4)一個進程可以打開的文件個數是有限制的,使用 ulimit -a 可以查看

那么在 linux 中,當我們打開一個文件的時候,會返回一個 fd,fd 是一種資源,在內核中是怎么維護這些資源的呢 ?當關閉一個文件的時候,會釋放這個 fd,釋放的時候又是怎么釋放的呢 ?

可以想象,如果讓我們自己來實現的話,我們會選擇一個 bitmap 來維護 fd 的被使用情況。系統默認情況下,一個進程可以打開的文件個數是 1024,我們就需要維護一個長度為 1024 的 bitmap。如下圖所示,表示一個長度為 1024 的 bitmap,bitmap 的下標從 0 到 1023 表示 1024 個 fd,bitmap 中的內容 1 表示 fd 被使用,0 表示 fd 沒有被使用。下圖表示 fd 0、1、2、501 被使用,其它的 fd 沒有被使用。

那么當我們打開一個文件的時候,是怎么分配 fd 的呢,是每次都要遍歷 bitmap,從中選擇一個空閑的 fd 來返回嗎 ?這種方式是最基礎的方法,當然是可行的。缺點在于,每次都要遍歷 bitmap,如果 bitmap 0~1000 都已經被使用,1001 沒有沒使用,這個時候我們就需要做 1000 次無用的查詢,效率比較低。當我們關閉文件,釋放 fd 的時候,是比較好理解的,直接使用 fd 作為下標,找到對應的 bit,直接將該 bit 設置為 0 即可。

1 fd 上下邊界

fd 最小是 0,最大可以使用 ulimit -a 來查看。默認情況下,系統允許一個進程最多打開 1024 個文件,所以 fd 最大值為 1023。所以默認情況下,進程內的 fd 的取值范圍是 [0, 1023]。

2 申請 fd

2.1 數據結構 struct fdtable 和函數 find_next_fd

struct fdtable 中有以下幾個成員和 fd 的維護有關。

struct fdtable {// 進程能打開的文件個數的最大值unsigned int max_fds;...// bitmap,一個 bit 表示一個 fdunsigned long *open_fds;// bitmap,一個 bit 表示 BITS_PER_LONG 個 fdunsigned long *full_fds_bits;...
};

在函數 find_next_fd 中,空閑 fd 的查找分了兩步來完成:

(1)先在 full_fds_bits 中查找,如果文件個數最多是 1024 個,在 64 位機器上 long 類型長度市是 64 個 bit。那么 full_fds_bit 的長度是 16(1024/64),第 0 bit 就能代表 open_fds 中的第 0 到第 63bit,第 1bit 能代表 open_fds 中的第 64 到 127bit,以此類推。只要第 64 到 127bit 有空閑的 fd,哪怕只有 1 個,那么在 full_fds_bit 中的第 1 bit 也會標志為空閑。

(2)在第一步中已經在 full_fds_bits 找到了空閑的 bit,這個 bit 能把查找范圍縮小到 64 個 bit 范圍之內。然后第二步中從 full_fds_bits 中查找具體空閑的 bit。

static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
{unsigned int maxfd = fdt->max_fds;unsigned int maxbit = maxfd / BITS_PER_LONG;unsigned int bitbit = start / BITS_PER_LONG;bitbit = find_next_zero_bit(fdt->full_fds_bits, maxbit, bitbit) * BITS_PER_LONG;if (bitbit > maxfd)return maxfd;if (bitbit > start)start = bitbit;return find_next_zero_bit(fdt->open_fds, maxfd, start);
}

使用兩級 bitmap 來查找空閑的 fd,對性能做了優化。

如果使用一級 bitmap,那么查找次數平均下來要 1024 次。

使用兩級 bitmap,查找次數平均下來是 16 + 64 = 80 次。16 是第一級 map 查找的次數,64 是第二級 bitmap 查找的次數。

3 釋放 fd

釋放 fd 相對來說好理解,直接使用 fd 做下標找到 bitmap 中對應的 bit,然后將 bit 清除即可。關閉 fd 的時候,會通過函數?__put_unused_fd() 最終調用 導函數 __clear_open_fd()。

static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
{__clear_bit(fd, fdt->open_fds);__clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
}

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

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

相關文章

【前端每日一題】day11

一個盒子(DIV)里有若干個小盒子,每個小盒子里還可能有多個小盒子 多層盒子結構。每個盒子都有一個唯一的id和 name 屬性。現在給出一個盒子的 id 請找到這個盒子并打開,輸出這個盒子內部所有小盒子的id和 name,并繼續打開這些小盒子輸出id和 …

【Unity】Unity項目轉抖音小游戲(四)一些常用方法

1.初始化 SDK會在Unity啟動前就初始化好,但是又有Init的接口,所以這里通過 StarkSDK.s_ContainerEnv 判斷有沒有初始化,沒有的話就手動初始化 public override void Init(string code, Action callback){Debug.Log("初始化抖音SDK"…

AIGC全面介紹

AIGC(Artificial Intelligence Generated Content),即生成式人工智能,是人工智能1.0時代進入2.0時代的重要標志。這一技術的出現,標志著人工智能從計算智能、感知智能邁向了認知智能的新階段。以下是關于AIGC的全面介紹…

基于manifest文件批量將coding的倉庫導入gitlab中

文章目錄 寫在前面的話背景編寫manifest文件最終效果 寫在前面的話 前面有講過通過manifest清單導入項目到gitlab中,但是實際的操作是不同gitlab實例之間的操作,然而對于在不同gitlab實例的repo遷移而言,顯然direct transfer會更合適。 背景…

民國漫畫雜志《時代漫畫》第21期.PDF

時代漫畫21.PDF: https://url03.ctfile.com/f/1779803-1248634754-017e2b?p9586 (訪問密碼: 9586) 《時代漫畫》的雜志在1934年誕生了,截止1937年6月戰爭來臨被迫停刊共發行了39期。 ps: 資源來源網絡!

代碼隨想錄算法訓練營Day49 | 123.買賣股票的最佳時機III、188.買賣股票的最佳時機IV | Python | 個人記錄向

本文目錄 123.買賣股票的最佳時機III做題看文章 188.買賣股票的最佳時機IV做題 以往忽略的知識點小結個人體會 123.買賣股票的最佳時機III 代碼隨想錄:123.買賣股票的最佳時機III Leetcode:123.買賣股票的最佳時機III 做題 無思路。 看文章 確定dp數…

結構型模式之橋接模式

文章目錄 概述原理結構圖代碼示例 小結 概述 橋接模式(bridge pattern) 的定義是:將抽象部分與它的實現部分分離,使它們都可以獨立地變化。 橋接模式用一種巧妙的方式處理多層繼承存在的問題,用抽象關聯來取代傳統的多層繼承,將類之間的靜態繼承關系轉…

使用位掩碼的權限設計

使用位掩碼的權限設計 權限系統的設計幾乎是每個系統都必需的模塊。 下面就聊一聊基本設計的思路。 位掩碼(BitMask),是位(Bit)和掩碼(Mask)的組合詞。 “位”指代著二進制數據當中的二進制位…

基于深度學習OCR文本識別系統源碼(帶界面)

第一步:概要 基于深度學習OCR文本識別分為兩個模塊:DBNet和CRNN。 DBNet是基于分割的文本檢測算法,算法將可微分二值化模塊(Differentiable Binarization)引入了分割模型,使得模型能夠通過自適應的閾值圖進行二值化,并…

Postgresql 基礎學習

一、介紹 PostgreSQL是一個開源的關系型數據庫管理系統(RDBMS),它支持SQL語言的所有功能,具有可擴展性、高并發性和可靠性等特點。 以下是一些 PostgreSQL 的特點: 開源:PostgreSQL是一個非常受歡迎的開源…

Python-溫故知新

1快速打開.ipynb文件 安裝好anaconda后,在需要打開notebook的文件夾中, shift鍵右鍵——打開powershell窗口——輸入jupyter notebook 即可在該文件夾中打開notebook的頁面: 2 快速查看函數用法 光標放在函數上——shift鍵tab 3...

Docker鏡像源自動測試鏡像速度,并選擇速度最快的鏡像

國內執行如下代碼 bash <(curl -sSL https://gitee.com/xjxjin/scripts/raw/main/check_docker_registry.sh)國外執行如下代碼 bash <(curl -sSL https://github.com/xjxjin/scripts/raw/main/check_docker_registry.sh)如果有老鐵有比較不錯的鏡像源&#xff0c;可以提…

探索Python編程樂趣:制作氣泡反彈小游戲

新書上架~&#x1f447;全國包郵奧~ python實用小工具開發教程http://pythontoolsteach.com/3 歡迎關注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目錄 一、引言&#xff1a;Python編程的輕松入門 二、游戲實現原理&#xff1a;氣泡反彈的邏輯 …

探索生態農業,守護綠色家園

在繁忙的都市生活中&#xff0c;我們往往忽略了與自然和諧相處的重要性。而生態農業&#xff0c;正是讓我們重拾與大自然親密關系的橋梁。通過采用生態友好的耕作方式&#xff0c;生態農業不僅能夠提供健康、營養的農產品&#xff0c;還能夠保護生態環境&#xff0c;實現人與自…

Android高通 12/13靜默安裝和卸載

1、靜默安裝和靜默卸載 涉及代碼路徑感興趣可以去看下如下所示&#xff0c;這里不作重點贅述哈 Package Manger frameworks/base/services/java/com/android/server/pm/Settings.java frameworks/base/services/java/com/android/server/pm/PackageManagerService.java framew…

CCS基礎入門

視頻&#xff1a; CCS使用教程_嗶哩嗶哩_bilibili 創建工程 步驟一&#xff1a;創建 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 步驟二&#xff1a;選擇工程配置 步驟三&#xff1a;完成創建 編譯工程&#xff1a; 方法一&#xff08;最常用&#xff09;…

Excel中自動驗證URL網址鏈接有效性

下面表格中的網址有的可以打開&#xff0c;有的不能打開 在Excel中按下 Alt F11 鍵來打開VBA編輯器&#xff0c;選擇 插入 > 模塊&#xff0c;創建一個新的模塊&#xff0c;在新創建的模塊窗口中輸入以下代碼&#xff1a; Function 測試網址(ByVal URL As String) As Str…

$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams

問題描述 動態添加子view的時候&#xff0c;報crash&#xff0c;提示$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams 完整錯誤堆棧 :12.946 11951-11951/com.xx E/CrashReport: sys default last handle start! 11-16 12:21:13.041 11951-1195…

筆記-X86下用Docker運行ARM64編譯Libreoffice

初衷 針對惡略環境下的自適應&#xff0c;記個筆記&#xff0c;苦于沒有外網的arm架構環境&#xff0c;內網中安裝個arm類型的deb&#xff0c;難如登天&#xff0c;突然發現這個好東西。 參考引用 x86架構的Ubuntu上通過Docker運行ARM架構的系統 前提 docker已經安裝好 安…

UDP協議與TCP協議1.2

UDP UDP數據報UDP報頭UDP載荷 UDP的報文格式&#xff1a; 這里的UDP長度&#xff0c;描述了整個UDP數據報&#xff0c;占多少個字節&#xff0c;這里整個UDP長度最多是64kb 在UDP中校驗和就是使用CRC的方式來完成的 數據在網絡傳輸中是可能會出現錯誤的&#xff0c;例如比特翻…