【Linux】File 结构体,和 fd 的关系

本文详细探讨了Linux系统中File结构体的概念及其与文件描述符(fd)之间的联系。通过理解File结构体的内部工作原理,可以更好地了解内核如何管理和操作文件。文件描述符作为进程与打开文件交互的抽象接口,在系统调用中扮演关键角色。深入分析了File结构体的成员变量,包括文件位置指针、缓冲区管理等,阐述它们如何影响文件I/O操作。
摘要由CSDN通过智能技术生成

1. struct file
  struct file 结构体在 include/linux/fs.h 中定义。文件结构体代表一个打开的文件,系统中每个打开的文件在内核空间都有一个关联的 struct file。它由内核在打开文件时创
建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码中,struct file 的指针通常被命名为 file 或 filp 
 
下面我们来展示 struct file  最重要的成员:

1)mode_t  f_mode
   文件模式确定文件是可读的或者可写的(或者都是),通过 位FMODE_READ和 FMODE_WRITE。 

2)loff_t  f_pos
   当前读写位置, loff_t 在所有平台都是 64 位( 在 gcc术语里是 long long)。 驱动可以读这个值,如果它需要知道文件中的当前位置,但是正常地不应该改变它;读和写应当使用它们作为最后参数而收到的指针来更新一个位置,代替直接作用于 filp->f_pos。这个规则的一个例外是在 lseek  方法中,它的目的就是改变文件位置。

3)unsigned  int  f_flags
   这些是文件标志,例如 O_RDONLY,O_NONBLOCK,和 O_SYNC。驱动应当检查 O_NONBLOCK  标志来看是否是请求非阻塞操作;其他标志很少使用。特别地,应当检查读/写许可,使用 f_mode 而不是 f_flags。所有的标志在头文件 <linux/fcntl.h> 中定义。

4)struct file_operatio
在使用 `select` 函数进行 I/O 多路复用时,需要对返回值进行判断以确定有哪些文件描述符就绪。`select` 函数的返回值表示就绪文件描述符的数量,如果返回值为 0,则说明在超时时间内没有文件描述符就绪;如果返回值为 -1,则说明 `select` 函数调用失败。 在判断就绪的文件描述符时,可以使用 `FD_ISSET` 函数对每个文件描述符进行判断。`FD_ISSET` 函数返回值为非零表示该文件描述符存在于集合中,为零表示不存在于集合中。 如果需要统计有多少个文件描述符就绪,可以遍历文件描述符集合,对每个文件描述符调用 `FD_ISSET` 函数进行判断,并累加计数。 下面是一个简单的示例代码,用于统计有多少个文件描述符就绪: ```c #include <stdio.h> #include <stdlib.h> #include <sys/select.h> #include <unistd.h> int main() { fd_set rfds; // 用于存储文件描述符集合的 fd_set 结构体 int maxfd = STDIN_FILENO + 1; // 待监视的最大文件描述符值加一 struct timeval timeout = {5, 0}; // 超时时间为 5 秒 while (1) { FD_ZERO(&rfds); // 将读文件描述符集合清零 FD_SET(STDIN_FILENO, &rfds); // 将标准输入加入到读文件描述符集合 // 调用 select 函数进行 I/O 多路复用 int ret = select(maxfd, &rfds, NULL, NULL, &timeout); if (ret < 0) { perror("select error"); exit(1); } else if (ret == 0) { printf("timeout\n"); } else { int count = 0; // 遍历文件描述符集合,统计有多少个文件描述符就绪 for (int fd = 0; fd < maxfd; fd++) { if (FD_ISSET(fd, &rfds)) { count++; } } printf("%d file descriptor(s) are ready\n", count); // 如果标准输入可读,进行读操作 if (FD_ISSET(STDIN_FILENO, &rfds)) { char buf[1024]; int n = read(STDIN_FILENO, buf, sizeof(buf)); if (n < 0) { perror("read error"); exit(1); } else if (n == 0) { printf("EOF\n"); break; } else { printf("read: %s", buf); } } } } return 0; } ``` 在该程序中,当 `select` 函数返回时,程序首先遍历文件描述符集合,统计有多少个文件描述符就绪,然后通过 `FD_ISSET` 函数判断标准输入是否可读,如果可读则进行读操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值