日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

OS / Linux / 文件描述符以及 file 结构体

發(fā)布時間:2024/10/14 linux 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OS / Linux / 文件描述符以及 file 结构体 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

零、前言

程序可以理解為硬盤上的普通二進制文件;進程是加載到內(nèi)存中的二進制文件,除了加載到內(nèi)存中的二進制文件外,還附有所有對于該二進制文件描述信息的結構體,描述該進程的結構體叫PCB(進程控制塊),在這就不在討論。對于程序與進程,也就可以簡單地理解為是否有PCB(進程控制塊)。下面我們再來討論 PCB 與 file_struct 的關系。

在每一個PCB中,都有一個文件描述符表,通過文件描述符索引指向 file 結構體 (系統(tǒng)打開文件表)。

文件描述符在形式上是一個非負整數(shù),實際上,它是一個索引值,指向內(nèi)核為每一個進程所維護的該進程打開文件的記錄表,當程序打開一個現(xiàn)有文件或創(chuàng)建一個新文件時,內(nèi)核向進程返回一個文件描述符。也就是說,一個程序能夠訪問文件是因為給這個程序分配了文件描述符。

下面我們來討論 file 結構體里面具體有哪些內(nèi)容,file 結構體定義在 linux 系統(tǒng)中的(/kernels/include/linus/fs.h)文件中。

一、file 結構體

struct file {union{struct list_head fu_list; //文件對象鏈表指針 linux/include/linux/list.h 。struct rcu_head fu_rcuhead; //RCU(Read-Copy Update)是 Linux 2.6 內(nèi)核中新的鎖機制。} f_u;struct path f_path; //包含 dentry 和 mnt 兩個成員,用于確定文件路徑。 #define f_dentry f_path.dentry //f_path 的成員之一,當統(tǒng)的掛載根目錄。const struct file_operations; //*f_op; 與該文件相關聯(lián)的操作函數(shù)。atomic_t f_count; //文件的引用計數(shù)(有多少進程打開該文件)。unsigned int f_flags; //對應于 open 時指定的 flag 。mode_t f_mode; //讀寫模式:open 的 mod_t mode 參數(shù)。off_t f_pos; //該文件在當前進程中的文件偏移量。struct fown_struct f_owner; //該結構的作用是通過信號進行 I/O 時間通知的數(shù)據(jù)。unsigned int f_uid, f_gid; //文件所有者 id,所有者組 id。struct file_ra_state f_ra; //在 linux/include/linux/fs.h 中定義,文件預讀相關。unsigned long f_version; #ifdef CONFIG_SECURITYvoid *f_security; #endif   void *private_data; #ifdef CONFIG_EPOLLstruct list_head f_ep_links;spinlock_t f_ep_lock; #endif  struct address_space *f_mapping; };

其中重要參數(shù)參數(shù)介紹如下:

f_flags:表示打開文件的權限。

f_pos:表示當前讀寫文件的位置。

f_count:這個是一個相對來說比較重要的參數(shù),表示打開文件的引用計數(shù),如果有多個文件指針指向它,就會增加 f_count 的值。

f_mode:設置對文件的訪問模式,例如:只讀,只寫等。

當然其中還定義了許多結構體等內(nèi)容,這里就不在深究,下面我們來討論一個 fd 與 files_struct 的關系。files_struct 不同于 file 結構體。在這里要區(qū)分清楚。

二、file_operations

當我們打開一個文件時,操作系統(tǒng)為了管理所打開的文件,都會為這個文件創(chuàng)建一個 file 結構體,而 file 結構體中的 f_op 指針又指向 file_operations 結構體,這個結構體中的成員除了 struct module* owner 其余都是函數(shù)指針,file_operation 就是把系統(tǒng)調用和驅動程序關聯(lián)起來的關鍵數(shù)據(jù)結構。這個結構的每一個成員都對應著一個系統(tǒng)調用。讀取 file_operation 中相應的函數(shù)指針,接著把控制權轉交給函數(shù),從而完成了 Linux 設備驅動程序的工作。

我們先來看看 file_operations 結構體的實現(xiàn)和相關成員的介紹。

struct file_operations {struct module *owner;//指向擁有該模塊的指針;loff_t (*llseek)(struct file *, loff_t, int);//llseek 方法用作改變文件中的當前讀/寫位置, 并且新位置作為(正的)返回值.ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);//用來從設備中獲取數(shù)據(jù). 在這個位置的一個空指針導致 read 系統(tǒng)調用以 -EINVAL("Invalid argument") 失敗. 一個非負返回值代表了成功讀取的字節(jié)數(shù)( 返回值是一個 "signed size" 類型, 常常是目標平臺本地的整數(shù)類型).ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);//發(fā)送數(shù)據(jù)給設備. 如果 NULL, -EINVAL 返回給調用 write 系統(tǒng)調用的程序. 如果非負, 返回值代表成功寫的字節(jié)數(shù).ssize_t (*aio_read)(struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一個異步讀 -- 可能在函數(shù)返回前不結束的讀操作.ssize_t (*aio_write)(struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化設備上的一個異步寫.int (*readdir)(struct file *, void *, filldir_t);//對于設備文件這個成員應當為 NULL; 它用來讀取目錄, 并且僅對**文件系統(tǒng)**有用.unsigned int (*poll)(struct file *, struct poll_table_struct *);int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);long (*compat_ioctl)(struct file *, unsigned int, unsigned long);int (*mmap)(struct file *, struct vm_area_struct *);//mmap 用來請求將設備內(nèi)存映射到進程的地址空間. 如果這個方法是 NULL, mmap 系統(tǒng)調用返回 -ENODEV.int (*open)(struct inode *, struct file *);//打開一個文件int (*flush)(struct file *, fl_owner_t id);//flush 操作在進程關閉它的設備文件描述符的拷貝時調用;int (*release)(struct inode *, struct file *);//在文件結構被釋放時引用這個操作. 如同 open, release 可以為 NULL.int (*fsync)(struct file *, struct dentry *, int datasync);//用戶調用來刷新任何掛著的數(shù)據(jù).int (*aio_fsync)(struct kiocb *, int datasync);int (*fasync)(int, struct file *, int);int (*lock)(struct file *, int, struct file_lock *);//lock 方法用來實現(xiàn)文件加鎖; 加鎖對常規(guī)文件是必不可少的特性, 但是設備驅動幾乎從不實現(xiàn)它.ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);int (*check_flags)(int);int (*flock)(struct file *, int, struct file_lock *);ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);int (*setlease)(struct file *, long, struct file_lock **); };

?

文件描述符(file)是操作系統(tǒng)用來管理文件的數(shù)據(jù)結構,fd 就是 fd_array 的索引,FILE * 指針值就是該 fd_array 數(shù)組中元素的值,也就是 file 結構體的地址。

三、files_struct

每個進程用一個 files_struct 結構來記錄文件描述符的使用情況,這個 files_struct 結構稱為用戶打開文件表,它是進程的私有數(shù)據(jù)。

files_struct 結構在 include/linux/fdtable.h 中定義如下:

struct files_struct {atomic_t count; /* 共享該表的進程數(shù) */rwlock_t file_lock; /* 保護以下的所有域,以免在tsk->alloc_lock中的嵌套*/int max_fds; /*當前文件對象的最大數(shù)*/int max_fdset; /*當前文件描述符的最大數(shù)*/int next_fd;/*已分配的文件描述符加1 */struct file **fd; /* 指向文件對象指針數(shù)組的指針 */fd_set *close_on_exec; /*指向執(zhí)行exec( )時需要關閉的文件描述符*/fd_set *open_fds; /*指向打開文件描述符的指針*/fd_set close_on_exec_init; /* 執(zhí)行exec( )時需要關閉的文件描述符的初 值集合*/fd_set open_fds_init; /*文件描述符的初值集合*/struct file *fd_array[32]; /* 文件對象指針的初始化數(shù)組*/ };

?四、概括

?

參考:https://www.cnblogs.com/xiangtingshen/p/11961434.html

?

(SAW:Game Over!)

?

總結

以上是生活随笔為你收集整理的OS / Linux / 文件描述符以及 file 结构体的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。