Linux下file_struct
来源:互联网 发布:温州淘宝城 编辑:程序博客网 时间:2024/05/18 03:07
file结构体:
struct file结构体定义在include/Linux/fs.h中定义。文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中,struct file的指针通常被命名为file或filp。
struct file {
union {
struct list_head fu_list; 文件对象链表指针linux/include/linux/list.h
struct rcu_head fu_rcuhead; RCU是Linux 2.6内核中新的锁机制
} f_u;
struct path f_path; 包含dentry和mnt两个成员,用于确定文件路径
#define f_dentry f_path. dentry f_path的成员之一,当前文件的dentry结构
#define f_vfsmnt f_path.mnt 表示当前文件所在文件系统的挂载根目录
const struct file_operations *f_op; 与该文件相关联的操作函数
atomic_t f_count; 文件的引用计数(有多少进程打开该文件)
unsigned int f_flags; 对应于open时指定的flag
mode_t f_mode; 读写模式:open的mod_t mode参数
off_t f_pos; 该文件在当前进程中的文件偏移量
struct fown_struct f_owner; 该结构的作用是通过信号进行I/O时间通知的数据。
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_SECURITY
void *f_security;
#endif
void *private_data;
#ifdef CONFIG_EPOLL
struct list_head f_ep_links;
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
};
struct files_struct:
对于每个进程,包含一个files_struct结构,用来记录文件描述符的使用情况,定义在include/linux/file.h中
struct files_struct
{
atomic_t count; 使用该表的进程数
struct fdtable *fdt;
struct fdtable fdtab;
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd; 数值最小的最近关闭文件的文件描述符,下一个可用的文件描述符
struct embedded_fd_set close_on_exec_init; 执行exec时需要关闭的文件描述符初值集合
struct embedded_fd_set open_fds_init; 文件描述符的屏蔽字初值集合
struct file * fd_array[NR_OPEN_DEFAULT]; 默认打开的fd队列
};
struct fdtable {
unsigned int max_fds;
struct file ** fd; 指向打开的文件描述符列表的指针,开始的时候指向fd_array,当超过max_fds时,重新分配地址
fd_set *close_on_exec; 执行exec需要关闭的文件描述符位图(fork,exec即不被子进程继承的文件描述符)
fd_set *open_fds; 打开的文件描述符位图
struct rcu_head rcu;
struct fdtable *next;
};
这里着重说一下 fd。
fd: 文件描述符
fd只是一小整数,在open时产生。起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp。
文件描述符的操作(如: open)返回的是一个文件描述符,内核会在每个进程空间中维护一个文件描述符表, 所有打开的文件都将通过此表中的文件描述符来引用;而流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装,它的优点是带有I/O缓存。
每个进程在PCB(ProcessControl Block)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开问件的指针,现在我们明确一下:已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体。
那么我们用图表述一下:
那么下面我们举一个例子:
当我们运行的时候 我们看一下结果:
是按照我们预期输出到标准输出流的。
可是 我们如果把它写入文件里
我们发现,写入文件时先写入的是write,printf与fwrite后写入,并且被写入了两次。
当然与fork有关,那么,这又是为什么?
printf和fwrite都是库函数:结合已有知识,我们了解到当使用库函数命令时,打印消息并没有直接写到输出位置上,而是先把数据写到输出缓冲区,在刷新至输出位置。
1、当输出目标位置为输出到显示器时,则刷新方式是行刷新;
2、当输出目标位置为输出到文件中时,刷新方式由行缓冲变为全缓冲,全缓冲是指当把缓冲区写满后才能刷新。(或者强制刷新)
代码中printf和fwrite第一次打印,在fork操作之前,第二次在fork操作之后,原因是因为在fork操作前,printf和fwrite的输出命令将数据先写到缓冲区中,此时只执行了这两条命令,由于是全缓冲的刷新方式,所以这两条命令并不足以将缓存写满,所以数据暂存在缓冲区中;
然后进行fork创建子进程,由于fork创建出的父子进程代码共享,而数据不共享,各自私有一份,缓冲区中的数据都属于数据,因为父进程的残留数据还在缓冲区中,所以fork完毕后,父子进程将缓存中的数据各自存一份有父进程残留数据的数据,所以当父子进程各自刷新时,父子进程会各自执行一次printf和fwrite的输出命令(触发写时拷贝),所以命令就从原来的两条变为四条。
- Linux下file_struct
- Linux下file_struct以及文件描述符
- Linux之file_struct&fd(file descriptor)
- Linux中的file_struct、t命令以及atexit函数有关知识
- struct file 和 struct file_struct
- 关于文件描述符(file_struct)
- Linux下RTP编程(下)
- 下Linux下安装Python
- linux 下mount linux硬盘
- Linux下硬盘安装linux
- [Linux]:Linux下数学计算
- 【Linux】Linux 下C编程
- 【Linux】Linux 下socket 编程
- 【Linux】Linux下设置环境变量
- linux下pxe安装linux
- 【Linux】Linux下tar指令
- 【Linux】Linux下配置apache
- 【LINUX】Linux下的粘滞位
- (三十二)多页面切换组件
- 流的读取 、缓冲流、以及利用IO流读取文本和写文本的案例
- win7 64位svn右键菜单不显示问题
- CLGR_V2.1
- 【Java并发编程】02.Exchanger的使用
- Linux下file_struct
- 爬楼梯
- HTTP与HTTPS的区别
- 多线程
- 来到新家了
- 我前端学习问题笔记——JS初学篇
- Epoll LT和ET模式
- 为Html的select option元素添加图案
- pandas的合并