精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux 文件描述符 fd 究竟是什么?

系統(tǒng) Linux
一切的本源是通過(guò) fd 來(lái)操作的,那么,這個(gè) fd 究竟是什么?就這個(gè)點(diǎn)我們深入剖析。

 [[400487]]

前情概要

 我們知道有兩種文件讀寫(xiě)的方式,一種是系統(tǒng)調(diào)用的方式,操作的對(duì)象是一個(gè)整數(shù) fd,另一種是 Go 標(biāo)準(zhǔn)庫(kù)自己封裝的標(biāo)準(zhǔn)庫(kù) IO ,操作對(duì)象是 Go 封裝的 file 結(jié)構(gòu)體,但其內(nèi)部還是針對(duì)整數(shù) fd 的操作。所以一切的本源是通過(guò) fd 來(lái)操作的,那么,這個(gè) fd 究竟是什么?就這個(gè)點(diǎn)我們深入剖析。

fd 是什么?

fd 是 File descriptor 的縮寫(xiě),中文名叫做:文件描述符。文件描述符是一個(gè)非負(fù)整數(shù),本質(zhì)上是一個(gè)索引值(這句話(huà)非常重要)。

什么時(shí)候拿到的 fd ?

當(dāng)打開(kāi)一個(gè)文件時(shí),內(nèi)核向進(jìn)程返回一個(gè)文件描述符( open 系統(tǒng)調(diào)用得到 ),后續(xù) read、write 這個(gè)文件時(shí),則只需要用這個(gè)文件描述符來(lái)標(biāo)識(shí)該文件,將其作為參數(shù)傳入 read、write 。

fd 的值范圍是什么?

在 POSIX 語(yǔ)義中,0,1,2 這三個(gè) fd 值已經(jīng)被賦予特殊含義,分別是標(biāo)準(zhǔn)輸入( STDIN_FILENO ),標(biāo)準(zhǔn)輸出( STDOUT_FILENO ),標(biāo)準(zhǔn)錯(cuò)誤( STDERR_FILENO )。

文件描述符是有一個(gè)范圍的:0 ~ OPEN_MAX-1 ,最早期的 UNIX 系統(tǒng)中范圍很小,現(xiàn)在的主流系統(tǒng)單就這個(gè)值來(lái)說(shuō),變化范圍是幾乎不受限制的,只受到系統(tǒng)硬件配置和系統(tǒng)管理員配置的約束。

你可以通過(guò) ulimit 命令查看當(dāng)前系統(tǒng)的配置: 

  1. ➜  ulimit -n  
  2. 4864 

如上,我系統(tǒng)上進(jìn)程默認(rèn)最多打開(kāi) 4864 文件。

窺探 Linux 內(nèi)核

fd 究竟是什么?必須去 Linux 內(nèi)核看一眼。

用戶(hù)使用系統(tǒng)調(diào)用 open 或者 creat 來(lái)打開(kāi)或創(chuàng)建一個(gè)文件,用戶(hù)態(tài)得到的結(jié)果值就是 fd ,后續(xù)的 IO 操作全都是用 fd 來(lái)標(biāo)識(shí)這個(gè)文件,可想而知內(nèi)核做的操作并不簡(jiǎn)單,我們接下來(lái)就是要揭開(kāi)這層面紗。

task_struct

首先,我們知道進(jìn)程的抽象是基于 struct task_struct 結(jié)構(gòu)體,這是 Linux 里面最復(fù)雜的結(jié)構(gòu)體之一 ,成員字段非常多,我們今天不需要詳解這個(gè)結(jié)構(gòu)體,我稍微簡(jiǎn)化一下,只提取我們今天需要理解的字段如下: 

  1. struct task_struct {  
  2.     // ...  
  3.     /* Open file information: */  
  4.     struct files_struct     *files;  
  5.     // ...  

files; 這個(gè)字段就是今天的主角之一,files 是一個(gè)指針,指向一個(gè)為 struct files_struct 的結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體就是用來(lái)管理該進(jìn)程打開(kāi)的所有文件的管理結(jié)構(gòu)。

重點(diǎn)理解一個(gè)概念:

struct task_struct 是進(jìn)程的抽象封裝,標(biāo)識(shí)一個(gè)進(jìn)程,在 Linux 里面的進(jìn)程各種抽象視角,都是這個(gè)結(jié)構(gòu)體給到你的。當(dāng)創(chuàng)建一個(gè)進(jìn)程,其實(shí)也就是 new 一個(gè) struct task_struct 出來(lái);

files_struct

好,上面通過(guò)進(jìn)程結(jié)構(gòu)體引出了 struct files_struct 這個(gè)結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體管理某進(jìn)程打開(kāi)的所有文件的管理結(jié)構(gòu),這個(gè)結(jié)構(gòu)體本身是比較簡(jiǎn)單的: 

  1. /*  
  2.  * Open file table structure  
  3.  */  
  4. struct files_struct {  
  5.     // 讀相關(guān)字段  
  6.     atomic_t count;  
  7.     bool resize_in_progress;  
  8.     wait_queue_head_t resize_wait;  
  9.     // 打開(kāi)的文件管理結(jié)構(gòu)  
  10.     struct fdtable __rcu *fdt;  
  11.     struct fdtable fdtab;  
  12.     // 寫(xiě)相關(guān)字段  
  13.     unsigned int next_fd;  
  14.     unsigned long close_on_exec_init[1];  
  15.     unsigned long open_fds_init[1];  
  16.     unsigned long full_fds_bits_init[1];  
  17.     struct file * fd_array[NR_OPEN_DEFAULT];  
  18. }; 

files_struct 這個(gè)結(jié)構(gòu)體我們說(shuō)是用來(lái)管理所有打開(kāi)的文件的。怎么管理?本質(zhì)上就是數(shù)組管理的方式,所有打開(kāi)的文件結(jié)構(gòu)都在一個(gè)數(shù)組里。這可能會(huì)讓你疑惑,數(shù)組在那里?有兩個(gè)地方:

  1.  struct file * fd_array[NR_OPEN_DEFAULT] 是一個(gè)靜態(tài)數(shù)組,隨著 files_struct 結(jié)構(gòu)體分配出來(lái)的,在 64 位系統(tǒng)上,靜態(tài)數(shù)組大小為 64;
  2.  struct fdtable 也是個(gè)數(shù)組管理結(jié)構(gòu),只不過(guò)這個(gè)是一個(gè)動(dòng)態(tài)數(shù)組,數(shù)組邊界是用字段描述的;

思考:為什么會(huì)有這種靜態(tài) + 動(dòng)態(tài)的方式?

性能和資源的權(quán)衡 !大部分進(jìn)程只會(huì)打開(kāi)少量的文件,所以靜態(tài)數(shù)組就夠了,這樣就不用另外分配內(nèi)存。如果超過(guò)了靜態(tài)數(shù)組的閾值,那么就動(dòng)態(tài)擴(kuò)展。

可以回憶下,這個(gè)是不是跟 inode 的直接索引,一級(jí)索引的優(yōu)化思路類(lèi)似。

fdtable

簡(jiǎn)單介紹下 fdtable 結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體就是封裝用來(lái)管理 fd 的結(jié)構(gòu)體,fd 的秘密就在這個(gè)里面。簡(jiǎn)化結(jié)構(gòu)體如下: 

  1. struct fdtable {  
  2.     unsigned int max_fds;  
  3.     struct file __rcu **fd;      /* current fd array */  
  4. }; 

注意到 fdtable.fd 這個(gè)字段是一個(gè)二級(jí)指針,什么意思?

就是指向 fdtable.fd 是一個(gè)指針字段,指向的內(nèi)存地址還是存儲(chǔ)指針的(元素指針類(lèi)型為  struct file * )。換句話(huà)說(shuō),fdtable.fd 指向一個(gè)數(shù)組,數(shù)組元素為指針(指針類(lèi)型為 struct file *)。

其中 max_fds 指明數(shù)組邊界。

files_struct 小結(jié)

file_struct 本質(zhì)上是用來(lái)管理所有打開(kāi)的文件的,內(nèi)部的核心是由一個(gè)靜態(tài)數(shù)組和動(dòng)態(tài)數(shù)組管理結(jié)構(gòu)實(shí)現(xiàn)。

還記得上面我們說(shuō)文件描述符 fd 本質(zhì)上就是索引嗎?這里就把概念接上了,fd 就是這個(gè)數(shù)組的索引,也就是數(shù)組的槽位編號(hào)而已。 通過(guò)非負(fù)數(shù) fd 就能拿到對(duì)應(yīng)的 struct file 結(jié)構(gòu)體的地址。

我們把概念串起來(lái)(注意,這里為了突出 fd 的本質(zhì),把 fdtable 管理簡(jiǎn)化掉):

  •  fd 真的就是 files 這個(gè)字段指向的指針數(shù)組的索引而已(僅此而已)。通過(guò) fd 能夠找到對(duì)應(yīng)文件的 struct file 結(jié)構(gòu)體;

file

現(xiàn)在我們知道了 fd 本質(zhì)是數(shù)組索引,數(shù)組元素是 struct file 結(jié)構(gòu)體的指針。那么這里就引出了一個(gè) struct file 的結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體又是用來(lái)干什么的呢?

這個(gè)結(jié)構(gòu)體是用來(lái)表征進(jìn)程打開(kāi)的文件的。簡(jiǎn)化結(jié)構(gòu)如下: 

  1. struct file {  
  2.     // ...  
  3.     struct path                     f_path;  
  4.     struct inode                    *f_inode;  
  5.     const struct file_operations    *f_op;  
  6.     atomic_long_t                    f_count;  
  7.     unsigned int                     f_flags;  
  8.     fmode_t                          f_mode;  
  9.     struct mutex                     f_pos_lock;  
  10.     loff_t                           f_pos;  
  11.     struct fown_struct               f_owner;  
  12.     // ...  

這個(gè)結(jié)構(gòu)體非常重要,它標(biāo)識(shí)一個(gè)進(jìn)程打開(kāi)的文件,下面解釋 IO 相關(guān)的幾個(gè)最重要的字段:

  •  f_path :標(biāo)識(shí)文件名
  •  f_inode :非常重要的一個(gè)字段,inode 這個(gè)是 vfs 的 inode 類(lèi)型,是基于具體文件系統(tǒng)之上的抽象封裝;
  •  f_pos :這個(gè)字段非常重要,偏移,對(duì),就是當(dāng)前文件偏移。還記得上一篇 IO 基礎(chǔ)里也提過(guò)偏移對(duì)吧,指的就是這個(gè),f_pos 在 open 的時(shí)候會(huì)設(shè)置成默認(rèn)值,seek 的時(shí)候可以更改,從而影響到 write/read 的位置;

思考問(wèn)題

思考問(wèn)題一:files_struct 結(jié)構(gòu)體只會(huì)屬于一個(gè)進(jìn)程,那么struct file 這個(gè)結(jié)構(gòu)體呢,是只會(huì)屬于某一個(gè)進(jìn)程?還是可能被多個(gè)進(jìn)程共享?

劃重點(diǎn):struct file 是屬于系統(tǒng)級(jí)別的結(jié)構(gòu),換句話(huà)說(shuō)是可以共享與多個(gè)不同的進(jìn)程。

思考問(wèn)題二:什么時(shí)候會(huì)出現(xiàn)多個(gè)進(jìn)程的  fd  指向同一個(gè) file  結(jié)構(gòu)體?

比如 fork  的時(shí)候,父進(jìn)程打開(kāi)了文件,后面 fork 出一個(gè)子進(jìn)程。這種情況就會(huì)出現(xiàn)共享 file 的場(chǎng)景。如圖:

思考問(wèn)題三:在同一個(gè)進(jìn)程中,多個(gè) fd 可能指向同一個(gè) file 結(jié)構(gòu)嗎?

可以。dup  函數(shù)就是做這個(gè)的。 

  1. #include <unistd.h>  
  2. int dup(int oldfd);  
  3. int dup2(int oldfd, int newfd); 

inode

我們看到 struct file 結(jié)構(gòu)體里面有一個(gè) inode 的指針,也就自然引出了 inode 的概念。這個(gè)指向的 inode 并沒(méi)有直接指向具體文件系統(tǒng)的 inode ,而是操作系統(tǒng)抽象出來(lái)的一層虛擬文件系統(tǒng),叫做 VFS ( Virtual File System ),然后在 VFS 之下才是真正的文件系統(tǒng),比如 ext4 之類(lèi)的。

完整架構(gòu)圖如下:

思考:為什么會(huì)有這一層封裝呢?

其實(shí)很容里理解,就是解耦。如果讓 struct file 直接和 struct ext4_inode 這樣的文件系統(tǒng)對(duì)接,那么會(huì)導(dǎo)致 struct file 的處理邏輯非常復(fù)雜,因?yàn)槊繉?duì)接一個(gè)具體的文件系統(tǒng),就要考慮一種實(shí)現(xiàn)。所以操作系統(tǒng)必須把底下文件系統(tǒng)屏蔽掉,對(duì)外提供統(tǒng)一的 inode 概念,對(duì)下定義好接口進(jìn)行回調(diào)注冊(cè)。這樣讓 inode 的概念得以統(tǒng)一,Unix 一切皆文件的基礎(chǔ)就來(lái)源于此。

再來(lái)看一樣 VFS 的 inode 的結(jié)構(gòu): 

  1. struct inode {  
  2.     // 文件相關(guān)的基本信息(權(quán)限,模式,uid,gid等)  
  3.     umode_t             i_mode;  
  4.     unsigned short      i_opflags;  
  5.     kuid_t              i_uid;  
  6.     kgid_t              i_gid;  
  7.     unsigned int        i_flags; 
  8.     // 回調(diào)函數(shù)  
  9.     const struct inode_operations   *i_op;  
  10.     struct super_block              *i_sb;  
  11.     struct address_space            *i_mapping;  
  12.     // 文件大小,atime,ctime,mtime等  
  13.     loff_t              i_size;  
  14.     struct timespec64   i_atime;  
  15.     struct timespec64   i_mtime;  
  16.     struct timespec64   i_ctime;  
  17.     // 回調(diào)函數(shù)  
  18.     const struct file_operations    *i_fop;  
  19.     struct address_space            i_data;  
  20.     // 指向后端具體文件系統(tǒng)的特殊數(shù)據(jù) 
  21.     void    *i_private;     /* fs or device private pointer */  
  22. }; 

其中包括了一些基本的文件信息,包括 uid,gid,大小,模式,類(lèi)型,時(shí)間等等。

一個(gè) vfs 和 后端具體文件系統(tǒng)的紐帶:i_private 字段。**用來(lái)傳遞一些具體文件系統(tǒng)使用的數(shù)據(jù)結(jié)構(gòu)。

至于 i_op 回調(diào)函數(shù)在構(gòu)造 inode 的時(shí)候,就注冊(cè)成了后端的文件系統(tǒng)函數(shù),比如 ext4 等等。

思考問(wèn)題:通用的 VFS 層,定義了所有文件系統(tǒng)通用的 inode,叫做 vfs inode,而后端文件系統(tǒng)也有自身特殊的 inode 格式,該格式是在 vfs inode 之上進(jìn)行擴(kuò)展的,怎么通過(guò) vfs inode 怎么得到具體文件系統(tǒng)的 inode 呢?

下面以 ext4 文件系統(tǒng)舉例(因?yàn)樗械奈募到y(tǒng)套路一樣),ext4 的 inode 類(lèi)型是 struct ext4_inode_info 。

劃重點(diǎn):方法其實(shí)很簡(jiǎn)單,這個(gè)是屬于 c 語(yǔ)言一種常見(jiàn)的(也是特有)編程手法:強(qiáng)轉(zhuǎn)類(lèi)型。vfs inode 出生就和 ext4_inode_info 結(jié)構(gòu)體分配在一起的,直接通過(guò) vfs inode 結(jié)構(gòu)體的地址強(qiáng)轉(zhuǎn)類(lèi)型就能得到 ext4_inode_info 結(jié)構(gòu)體。 

  1. struct ext4_inode_info {  
  2.     // ext4 inode 特色字段  
  3.     // ...      
  4.     // 重要!!!  
  5.     struct inode    vfs_inode;    
  6. }; 

舉個(gè)例子,現(xiàn)已知 inode 地址和 vfs_inode 字段的內(nèi)偏移如下:

  •  inode 的地址為 0xa89be0;
  •  ext4_inode_info 里有個(gè)內(nèi)嵌字段 vfs_inode,類(lèi)型為 struct inode ,該字段在結(jié)構(gòu)體內(nèi)偏移為 64 字節(jié);

則可以得到:

ext4_inode_info 的地址為

  1. (struct ext4_inode_info *)(0xa89be0 - 64) 

強(qiáng)轉(zhuǎn)方法使用了一個(gè)叫做 container_of 的宏,如下: 

  1. // 強(qiáng)轉(zhuǎn)函數(shù)  
  2. static inline struct ext4_inode_info *EXT4_I(struct inode *inode)  
  3.  
  4.    return container_of(inode, struct ext4_inode_info, vfs_inode);  
  5.  
  6. // 強(qiáng)轉(zhuǎn)實(shí)際封裝  
  7. #define container_of(ptr, type, member) \  
  8.     (type *)((char *)(ptr) - (char *) &((type *)0)->member)  
  9. #endif 

所以,你懂了嗎?

分配 inode 的時(shí)候,其實(shí)分配的是 ext4_inode_info 結(jié)構(gòu)體,包含了 vfs inode,然后對(duì)外給出去 vfs_inode 字段的地址即可。VFS 層拿 inode 的地址使用,底下文件系統(tǒng)強(qiáng)轉(zhuǎn)類(lèi)型后,取外層的 inode 地址使用。

舉個(gè) ext4 文件系統(tǒng)的例子: 

  1. static struct inode *ext4_alloc_inode(struct super_block *sb)  
  2.  
  3.     struct ext4_inode_info *ei;  
  4.     // 內(nèi)存分配,分配 ext4_inode_info 的地址  
  5.     ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS);  
  6.     // ext4_inode_info 結(jié)構(gòu)體初始化  
  7.     // 返回 vfs_inode 字段的地址  
  8.     return &ei->vfs_inode;  

vfs 拿到的就是這個(gè) inode 地址。

劃重點(diǎn):inode 的內(nèi)存由后端文件系統(tǒng)分配,vfs inode 結(jié)構(gòu)體內(nèi)嵌在不同的文件系統(tǒng)的 inode 之中。不同的層次用不同的地址,ext4 文件系統(tǒng)用 ext4_inode_info 的結(jié)構(gòu)體的地址,vfs 層用 ext4_inode_info.vfs_inode 字段的地址。

這種用法在 C 語(yǔ)言編程中很常見(jiàn),算是 C 的特色了(仔細(xì)想想,這種用法和面向?qū)ο蟮亩鄳B(tài)的實(shí)現(xiàn)異曲同工)。

思考問(wèn)題:怎么理解 vfs inode 和 ext2_inode_info,ext4_inode_info 等結(jié)構(gòu)體的區(qū)別?

所有文件系統(tǒng)共性的東西抽象到 vfs inode ,不同文件系統(tǒng)差異的東西放在各自的 inode 結(jié)構(gòu)體中。

小結(jié)梳理

當(dāng)用戶(hù)打開(kāi)一個(gè)文件,用戶(hù)只得到了一個(gè) fd 句柄,但內(nèi)核做了很多事情,梳理下來(lái),我們得到幾個(gè)關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),這幾個(gè)數(shù)據(jù)結(jié)構(gòu)是有層次遞進(jìn)關(guān)系的,我們簡(jiǎn)單梳理下:

  1.  進(jìn)程結(jié)構(gòu) task_struct :表征進(jìn)程實(shí)體,每一個(gè)進(jìn)程都和一個(gè) task_struct 結(jié)構(gòu)體對(duì)應(yīng),其中 task_struct.files 指向一個(gè)管理打開(kāi)文件的結(jié)構(gòu)體 fiels_struct ;
  2.  文件表項(xiàng)管理結(jié)構(gòu) files_struct :用于管理進(jìn)程打開(kāi)的 open 文件列表,內(nèi)部以數(shù)組的方式實(shí)現(xiàn)(靜態(tài)數(shù)組和動(dòng)態(tài)數(shù)組結(jié)合)。返回給用戶(hù)的 fd 就是這個(gè)數(shù)組的編號(hào)索引而已,索引元素為 file 結(jié)構(gòu);
  •  files_struct 只從屬于某進(jìn)程;

    3.  文件 file 結(jié)構(gòu):表征一個(gè)打開(kāi)的文件,內(nèi)部包含關(guān)鍵的字段有:當(dāng)前文件偏移,inode 結(jié)構(gòu)地址;

  •  該結(jié)構(gòu)雖然由進(jìn)程觸發(fā)創(chuàng)建,但是 file  結(jié)構(gòu)可以在進(jìn)程間共享;

    4.   vfs inode 結(jié)構(gòu)體:文件 file 結(jié)構(gòu)指向 的是 vfs 的 inode ,這個(gè)是操作系統(tǒng)抽象出來(lái)的一層,用于屏蔽后端各種各樣的文件系統(tǒng)的 inode 差異;

  •  inode 這個(gè)具體進(jìn)程無(wú)關(guān),是文件系統(tǒng)級(jí)別的資源;

    5.  ext4 inode 結(jié)構(gòu)體(指代具體文件系統(tǒng) inode ):后端文件系統(tǒng)的 inode 結(jié)構(gòu),不同文件系統(tǒng)自定義的結(jié)構(gòu)體,ext2 有 ext2_inode_info,ext4 有ext4_inode_info,minix 有 minix_inode_info,這些結(jié)構(gòu)里都是內(nèi)嵌了一個(gè) vfs inode 結(jié)構(gòu)體,原理相同;

完整的架構(gòu)圖:

思考實(shí)驗(yàn)

現(xiàn)在我們已經(jīng)徹底了解 fd 這個(gè)所謂的非負(fù)整數(shù)代表的深層含義了,我們可以準(zhǔn)備一些 IO 的思考舉一反三。

文件讀寫(xiě)( IO )的時(shí)候會(huì)發(fā)生什么?

  •  在完成 write 操作后,在文件 file  中的當(dāng)前文件偏移量會(huì)增加所寫(xiě)入的字節(jié)數(shù),如果這導(dǎo)致當(dāng)前文件偏移量超處了當(dāng)前文件長(zhǎng)度,則會(huì)把 inode 的當(dāng)前長(zhǎng)度設(shè)置為當(dāng)前文件偏移量(也就是文件變長(zhǎng))
  •  O_APPEND  標(biāo)志打開(kāi)一個(gè)文件,則相應(yīng)的標(biāo)識(shí)會(huì)被設(shè)置到文件 file  狀態(tài)的標(biāo)識(shí)中,每次對(duì)這種具有追加寫(xiě)標(biāo)識(shí)的文件執(zhí)行 write 操作的時(shí)候,file 的當(dāng)前文件偏移量首先會(huì)被設(shè)置成 inode 結(jié)構(gòu)體中的文件長(zhǎng)度,這就使得每次寫(xiě)入的數(shù)據(jù)都追加到文件的當(dāng)前尾端處(該操作對(duì)用戶(hù)態(tài)提供原子語(yǔ)義);
  •  若一個(gè)文件 seek 定位到文件當(dāng)前的尾端,則 file 中的當(dāng)前文件偏移量設(shè)置成 inode 的當(dāng)前文件長(zhǎng)度;
  •  seek 函數(shù)值修改 file 中的當(dāng)前文件偏移量,不進(jìn)行任何 I/O 操作;
  •  每個(gè)進(jìn)程對(duì)有它自己的 file,其中包含了當(dāng)前文件偏移,當(dāng)多個(gè)進(jìn)程寫(xiě)同一個(gè)文件的時(shí)候,由于一個(gè)文件 IO 最終只會(huì)是落到全局的一個(gè) inode 上,這種并發(fā)場(chǎng)景則可能產(chǎn)生用戶(hù)不可預(yù)期的結(jié)果;

總結(jié)

回到初心,理解 fd 的概念有什么用?

一切 IO 的行為到系統(tǒng)層面都是以 fd 的形式進(jìn)行。無(wú)論是 C/C++,Go,Python,JAVA 都是一樣,任何語(yǔ)言都是一樣,這才是最本源的東西,理解了 fd 關(guān)聯(lián)的一系列結(jié)構(gòu),你才能對(duì) IO 游刃有余。

簡(jiǎn)要的總結(jié):

  1.  從姿勢(shì)上來(lái)講,用戶(hù) open 文件得到一個(gè)非負(fù)數(shù)句柄 fd,之后針對(duì)該文件的 IO 操作都是基于這個(gè) fd ;
  2.  文件描述符 fd 本質(zhì)上來(lái)講就是數(shù)組索引,fd 等于 5 ,那對(duì)應(yīng)數(shù)組的第 5 個(gè)元素而已,該數(shù)組是進(jìn)程打開(kāi)的所有文件的數(shù)組,數(shù)組元素類(lèi)型為 struct file;
  3.  結(jié)構(gòu)體 task_struct 對(duì)應(yīng)一個(gè)抽象的進(jìn)程,files_struct 是這個(gè)進(jìn)程管理該進(jìn)程打開(kāi)的文件數(shù)組管理器。fd 則對(duì)應(yīng)了這個(gè)數(shù)組的編號(hào),每一個(gè)打開(kāi)的文件用 file 結(jié)構(gòu)體表示,內(nèi)含當(dāng)前偏移等信息;
  4.  file 結(jié)構(gòu)體可以為進(jìn)程間共享,屬于系統(tǒng)級(jí)資源,同一個(gè)文件可能對(duì)應(yīng)多個(gè) file 結(jié)構(gòu)體,file 內(nèi)部有個(gè) inode 指針,指向文件系統(tǒng)的 inode;
  5.  inode 是文件系統(tǒng)級(jí)別的概念,只由文件系統(tǒng)管理維護(hù),不因進(jìn)程改變( file 是進(jìn)程出發(fā)創(chuàng)建的,進(jìn)程 open 同一個(gè)文件會(huì)導(dǎo)致多個(gè) file ,指向同一個(gè) inode );

回顧一眼架構(gòu)圖:

~完~

后記

內(nèi)核把最復(fù)雜的活干了,只暴露給您最簡(jiǎn)單的一個(gè)非負(fù)整數(shù) fd 。所以,絕大部分場(chǎng)景會(huì)用fd 就行,倒不用想太多。當(dāng)然如果能再深入看一眼知其所以然是最好不過(guò)。本文分享是基礎(chǔ)準(zhǔn)備篇,希望能給你帶來(lái)不一樣的 IO 視角。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 良許Linux
相關(guān)推薦

2025-01-10 15:13:38

2011-02-16 16:13:40

Debian

2018-09-10 13:47:21

數(shù)據(jù)科學(xué)統(tǒng)計(jì)學(xué)決策

2015-09-29 09:47:14

2019-05-27 15:30:44

Node.jsJavaScript前端

2015-08-26 09:54:19

物聯(lián)網(wǎng)

2014-07-28 08:28:38

Windows

2009-07-30 14:43:30

認(rèn)識(shí)BSM

2011-08-04 13:24:28

IT運(yùn)維

2014-08-07 10:32:02

Windows微軟

2012-05-28 22:49:50

PureView

2022-06-13 09:51:35

UWB超寬帶無(wú)線(xiàn)載波通信技術(shù)

2009-05-11 18:56:47

服務(wù)器虛擬化Vmware

2025-06-25 14:18:36

LAMLAMsGUI

2020-07-08 08:09:08

邊緣計(jì)算邊緣云云平臺(tái)

2020-12-17 17:33:47

MLOps大數(shù)據(jù)數(shù)據(jù)

2021-08-09 05:19:08

Provider 前端前端代碼

2021-03-08 21:44:33

以太坊區(qū)塊鏈比特幣

2014-06-27 09:35:16

機(jī)器學(xué)習(xí)

2022-02-07 15:20:53

去中心化加密經(jīng)濟(jì)學(xué)加密貨幣
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲精品成人无码毛片| 亚洲精品永久www嫩草| 九九精品在线观看视频| theporn国产在线精品| 亚洲成人黄色影院| 麻豆亚洲一区| 国产有码在线观看| 日韩一级在线| 日韩中文在线视频| 国产精品一区二区人妻喷水| 欧美xxxxxx| 亚洲视频免费在线观看| 鲁片一区二区三区| 国产熟女精品视频| 久久精品盗摄| 欧美高清videos高潮hd| 五月天综合视频| 中文字幕日韩在线| 欧美天天综合网| www.日本少妇| 大片免费在线观看| 久久日韩粉嫩一区二区三区| 亚洲在线免费视频| 日韩不卡高清视频| 99视频+国产日韩欧美| 日韩中文视频免费在线观看| 精品人妻一区二区三区香蕉| 午夜久久av| 欧美日韩在线免费视频| 国产精品333| 青草av在线| 综合激情成人伊人| 亚洲成色www久久网站| 少妇高潮一区二区三区69| 捆绑调教一区二区三区| 日韩av片永久免费网站| 成年人免费看毛片| 欧美精品国产一区二区| 这里只有精品在线播放| 国产呦小j女精品视频| 91精品久久久久久综合五月天 | 日韩精品 欧美| 成人日日夜夜| 成人欧美一区二区三区白人| 日韩国产伦理| 黄色在线视频观看网站| 99免费精品视频| 国产在线精品一区二区中文| 亚洲国产精品欧美久久| 国产尤物一区二区| 91久久嫩草影院一区二区| 中文字幕人妻一区二区在线视频| 久久精品国语| 日本亚洲欧洲色α| 美女又爽又黄免费视频| 久久精品首页| 日韩av大片免费看| 国产99免费视频| 日韩精品色哟哟| 国产成人综合亚洲| 国模私拍一区二区| 秋霞电影一区二区| 成人a免费视频| 国产日产亚洲系列最新| 久久精品二区亚洲w码| 成人h猎奇视频网站| 国产露脸国语对白在线| 国产一区二区调教| 99r国产精品视频| 日韩在线视频第一页| 99精品热视频| 日产精品久久久一区二区| 阿v免费在线观看| 最新日韩av在线| 99re6这里有精品热视频| 肉肉视频在线观看| 精品二区三区线观看| 无码播放一区二区三区| 欧美1级2级| 欧美肥胖老妇做爰| 老熟女高潮一区二区三区| 136国产福利精品导航网址应用| 精品久久久久久久久久久久久久久久久| 成人做爰www看视频软件| 风间由美性色一区二区三区四区 | 久久久久九九九| 国产在线观看免费网站| 中文字幕亚洲一区二区va在线| 99亚洲国产精品| 123区在线| 欧美午夜免费电影| 91视频免费入口| 美日韩中文字幕| 久久久精品一区| 久久久久久久久久影院| 麻豆精品国产传媒mv男同| 97在线电影| 国产尤物视频在线| 亚洲黄色av一区| 久草在在线视频| 麻豆国产一区二区三区四区| 亚洲精品一区中文字幕乱码| 在线免费看av网站| 国产在线成人| 国产精品免费视频久久久| 亚洲精品911| 国产精品天干天干在观线| 男人的天堂avav| 国产麻豆一区| 精品视频在线播放免| www日韩在线| 日韩高清欧美激情| 国产精品乱码一区二区三区| av在线免费观看网| 精品国产1区2区| 欧美视频亚洲图片| 国产精品羞羞答答在线观看| 欧美福利视频网站| 国产精品久久婷婷| 国产日韩欧美精品在线| 亚洲精品蜜桃久久久久久| 亚洲三级电影| 国产亚洲美女久久| 天天综合网久久综合网| 国产黄人亚洲片| 亚洲一区二区在线看| 在线毛片观看| 亚洲福利在线看| 久久久久久久九九九九| 麻豆精品国产91久久久久久| 欧美性xxxx69| 美女高潮视频在线看| 欧美大片免费久久精品三p| 一本一本久久a久久| 久久久久久自在自线| 精品无人乱码一区二区三区的优势 | 久久蜜桃香蕉精品一区二区三区| 亚洲精品久久久久久久蜜桃臀| 91国产一区| 日韩一区二区久久久| 波多野结衣高清在线| 久久久久久久久久久电影| 免费在线观看亚洲视频| 精品人人人人| 91精品国产91久久| 凸凹人妻人人澡人人添| 亚洲大片精品永久免费| 亚洲v在线观看| 黄色综合网站| 国产伦精品一区二区三区高清版| 四虎av在线| 精品国内二区三区| 日韩精品一卡二卡| av在线一区二区| 欧美亚洲另类色图| 亚洲动漫精品| 国产激情久久久| jizz亚洲| 欧美电影一区二区三区| 三级av在线免费观看| 激情成人午夜视频| 亚洲天堂第一区| 97人人澡人人爽91综合色| 欧美黄色免费网站| 亚洲 欧美 激情 小说 另类| 一本到一区二区三区| 欧美大波大乳巨大乳| 免费美女久久99| 在线观看视频黄色| 亚洲天堂中文字幕在线观看| 久久久免费精品视频| 四虎精品成人免费网站| 色美美综合视频| 亚洲 欧美 国产 另类| 国产精品一卡二卡在线观看| 免费高清一区二区三区| 亚洲精品中文字幕99999| 国产精品久久在线观看| 黄网站app在线观看| 精品国偷自产国产一区| 成人免费毛片男人用品| 国产精品色哟哟网站| 中文字幕一二三区| 欧美专区18| 在线观看福利一区| 大桥未久女教师av一区二区| 欧美在线视频免费播放| 麻豆网站视频在线观看| 精品人伦一区二区色婷婷| 日韩 国产 欧美| 亚洲精品成人精品456| 免费无码一区二区三区| 麻豆成人免费电影| 丰满少妇久久久| 日本一本不卡| 3d蒂法精品啪啪一区二区免费| 男人天堂视频在线观看| 久久精品国产精品| 日韩电影免费| 日韩午夜中文字幕| 99久久久久久久久| 亚洲精品国产a久久久久久| 国产美女精品久久| 国产不卡免费视频| 九九热在线免费| 99国产一区| 久久久成人精品一区二区三区| 外国成人在线视频| 91系列在线播放| 欧美暴力调教| 97在线观看免费| 羞羞视频在线观看免费| 国产亚洲福利一区| 日韩在线视频第一页| 欧美一区在线视频| 亚洲av无码乱码国产精品fc2| 亚洲国产一区二区在线播放| 99成人在线观看| 亚洲国产精品激情在线观看| 日韩成人av一区二区| 国产乱码精品1区2区3区| 亚洲乱码国产一区三区| 亚洲精品欧美| 在线观看av的网址| 日韩欧美视频| 水蜜桃亚洲精品| 欧美激情极品| 国产日韩一区欧美| 日本免费精品| 91九色国产社区在线观看| 97人人做人人爽香蕉精品| 日本精品一区二区三区在线| 国产网站在线| 久久免费在线观看| 日本理论片午伦夜理片在线观看| 久久精品视频在线播放| h视频在线免费| 中文字幕av一区二区三区谷原希美| 亚洲欧美日韩免费| 日韩高清av在线| 日韩一级片免费观看| 亚洲精品xxx| 网站黄在线观看| 日韩电影中文字幕av| 特黄视频在线观看| 亚洲成人亚洲激情| 色欲av伊人久久大香线蕉影院| 日韩欧美不卡在线观看视频| 99久久久国产精品无码免费| 在线不卡中文字幕| 国产美女明星三级做爰| 91精品麻豆日日躁夜夜躁| 97在线视频人妻无码| 91精品国产综合久久精品app| 国产又粗又黄又爽视频| 91精品国模一区二区三区| 国产又黄又粗又长| 欧美一级夜夜爽| 亚洲精品97久久中文字幕| 亚洲国产免费av| 免费毛片在线| 在线亚洲午夜片av大片| 国产网站在线免费观看| 欧美激情a在线| 欧美男男tv网站在线播放| 日韩暖暖在线视频| 成人黄色毛片| 91亚洲va在线va天堂va国 | 日本不卡视频一二三区| 性chinese极品按摩| 国产美女精品在线| 国产精品扒开腿做爽爽爽a片唱戏| 91一区二区三区在线观看| 真实乱视频国产免费观看| 国产精品久久久久三级| 欧美精品久久久久性色| 午夜激情综合网| 中文字幕乱码视频| 日韩一区二区在线看片| 欧美视频在线观看一区二区三区| 日韩精品亚洲精品| 2021av在线| 欧美极品少妇与黑人| 成人激情综合| 91精品国产91久久久久青草| 人人精品亚洲| 在线视频福利一区| 在线视频观看日韩| 国产 porn| 成人晚上爱看视频| www.黄色在线| 亚洲午夜久久久久久久久久久 | av中文在线资源| 国产精品999999| 成人免费在线电影网| 亚洲啪啪av| 亚洲巨乳在线| 日本一二区免费| 91美女福利视频| 中文字幕av播放| 色婷婷av久久久久久久| www国产在线| 在线观看国产欧美| 91超碰国产在线| 成人网中文字幕| 国产成人高清| 人妻av无码专区| 久久成人18免费观看| 欧美精品欧美极品欧美激情| 自拍偷自拍亚洲精品播放| 久久久久久无码精品大片| 日韩精品一区二区三区视频在线观看 | 久99久精品视频免费观看| 97人妻精品一区二区三区免| 亚洲精品成a人| 国产精品视频a| 亚洲小视频在线| 伊人久久国产| 国产精品视频免费一区二区三区| 欧美aaaa视频| 手机视频在线观看| 久久综合久久99| 日本少妇bbwbbw精品| 欧美一级电影网站| 免费a级毛片在线播放| 国产精品成av人在线视午夜片| 成人在线tv视频| 精品一区二区三区无码视频| 激情av综合网| 成人一级黄色大片| 色婷婷av一区二区三区软件| 四虎成人免费在线| 欧美日韩成人在线视频| www.久久久.com| 在线视频福利一区| 老司机午夜精品99久久| 一级黄色录像毛片| 色婷婷综合在线| 久久久久久青草| 欧美性一区二区三区| 欧美日韩精品一区二区三区在线观看| 成人av在线不卡| 国产69精品久久久久毛片| 欧美黄色一级网站| 欧美一卡二卡在线| 色女人在线视频| 国产伦精品一区二区三区免 | 欧美大片久久久| 成人免费在线播放视频| 国产又粗又猛视频| 不卡av在线网站| 一区二区三区四区视频免费观看| 男女啪啪免费观看| 国产成人综合在线| 日本熟妇毛茸茸丰满| 精品99久久久久久| 成人在线黄色电影| 欧美日产一区二区三区在线观看| 麻豆久久婷婷| 国产一区二区三区四区在线| 欧美美女一区二区在线观看| 日韩av中文| ts人妖另类在线| 国产亚洲综合精品| 制服 丝袜 综合 日韩 欧美| 欧美最新大片在线看| 黄色片网站在线| 成人情视频高清免费观看电影| 精品成人免费| 亚洲av无码一区二区三区人| 欧美日韩你懂的| 毛片在线导航| 欧美精品一区二区三区在线四季 | 亚洲xxx自由成熟| 亚洲精品123区| 国产高清一区二区三区四区| 91精品免费在线| 美女视频在线免费| 日韩av在线一区二区三区| 国产一区二区免费视频| 国产一级做a爱免费视频| 亚洲欧美精品在线| 亚洲男男av| 日韩网址在线观看| 日韩一区在线看| 天堂视频中文在线| 成人黄色av网站| 国产一区二区三区成人欧美日韩在线观看| 久久婷婷五月综合| 日韩精品最新网址| 亚洲永久av| 男同互操gay射视频在线看| 91丨porny丨蝌蚪视频| 一区二区三区免费在线| 8090成年在线看片午夜| 日韩成人精品一区| 欧美在线一级片| 91精品国产91综合久久蜜臀| 中日韩脚交footjobhd| 26uuu成人|