首页 > 系统相关 >Linux系统下的文件描述符fd详解

Linux系统下的文件描述符fd详解

时间:2024-03-21 11:34:07浏览次数:31  
标签:文件 struct 描述符 fd file Linux test

文章目录


本作者从代码及源码的角度来总结探究文件描述符fd
参考:韦东山Linux嵌入式视频

文件描述符

Linux系统下一切皆文件。文件描述符是操作系统中用来唯一标识一个已打开文件的整数。本质上来说就是索引,即根据索引值寻找到对应的文件,可对其进行相应的操作。
使用open函数打开文件得到一个文件描述符,然后使用read和write函数通过文件描述符进行读写操作。所有执行I/O操作的系统调用都通过文件描述符来实现。

首先,创建一个test.c文件

vim test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        if(argc != 2){
             printf("Usage:%s <file>\n",argv[0]);
             return -1;
        }

        int fd = open(argv[1], O_RDONLY);

        printf("fd = %d\n",fd);
        while(1){
                sleep(100);
        }
        return 0;
}

编译,且运行打开test.c文件,&:表示后台运行,产生一个进程17985,打印文件描述符fd=3。

gcc -o test test.c 
/test test.c &

在这里插入图片描述
ps查看后台进程资源运行情况,切换到proc虚拟文件系统查看进程信息,进入fd目录查看对应文件描述符fd=3指向的就是打开test.c。其中fd=0,1,2分别对应标准输入、标准输出、标准错误
在这里插入图片描述

内核源码

  • open函数的系统调用会进入内核调用内核函数,一个进程就会产生struct task_struct结构体。** task_struct**结构体用于管理进程,包含了一个进程所需的所有信息。这也是PCB(进程控制块)
  • task_struct结构体的成员变量含有 struct files_struct *files结构体,files_struct结构体管理进程打开的所有文件的管理结构。
  • files_struct结构体的成员变量含有struct fdtable fdtab结构体,fdtable结构体管理进程的文件描述符表。
  • fdtable结构体的成员变量含有 struct file __rcu **fd结构体,file结构体表示一个打开的文件,并且包含了许多与文件操作相关的信息和属性

即:struct task_struct—>struct files_struct *files—>struct fdtable *fdt—>struct file **fd。
特别的,

 struct file __rcu **fd;      /* current fd array */

fd是一个二级指针,指向的类型是是struct file类型的指针,指向的地址存储的是strcut file类型的元素,地址里的元素strcut file指向的是struct file
fd.table.fd指向一个数组,数组元素为指针,指针类型为srtuct file *。
其中fd为一个数组,表中的元素为文件描述符(本质是索引或标识符)
0 :STDIN_FILENO 接收键盘的输入
1 :STDOUT_FILENO 向屏幕输出
2 :STDERR_FILENO 标准错误
3:上图打开的test.c文件
而这些又分别指向自己的struct file结构体,而这个结构体存放着该文件的一些重要信息
关系如下所示
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标签:文件,struct,描述符,fd,file,Linux,test
From: https://blog.csdn.net/qq_45009309/article/details/136644573

相关文章

  • [DPDK]Linux平台上DPDK入门指南(一)
    [DPDK]Linux平台上DPDK入门指南(一)1.1简介1.1.1文档地图1.2系统要求1.2.1X86上预先设置BIOS1.2.2编译DPDK1.2.3运行DPDK应用程序系统软件在Linux环境中使用Hugepages预留Hugepages给DPDK使用DPDK使用Hugepages配置内存用于DPDK使用1.3使用源码编译DPDK......
  • 排查linux 定时任务cron crontab
    简介:我在使用shell编程来实现DDNS服务的注册更新工作。但是老发现cron不正常工作。为所有的排查做个指导记录吧。一:检查cron编写*/1****echohello>>/root/out.log每分钟执行一次写入临时文件。#查看cron日志journalctl--no-pager--sincetoday-g'cron'Ma......
  • Linux系统连接手机USB网络共享后无法联网
    如题,离线安装了ubantu系统的服务器的所有网口都设置了静态ip,通过usb口外接手机usb网络共享后,通过ipaddr命令查看,发现usb0网卡没有拿到ip,通过尝试可以用以下命令解决sudodhclientusb0usb0重新向dhcp服务器请求ip,ipaddr看到获取到ip后可以pingbaidu.com试下,如果还......
  • linux下常见服务的搭建搜集 —— 筑梦之路
    安装JDK官网下载地址:https://www.oracle.com/java/technologies/downloads#创建目录mkdir/usr/local/java/#解压tar-zxvfjdk-8u333-linux-x64.tar.gz-C/usr/local/java/#配置环境变量vim/etc/profileexportexportJAVA_HOME=/usr/local/java/jdk1.8.0_2......
  • 大数据013_Linux(上传rz,下载sz,tar,zip,unzip)
    目录一、上传、下载1、通过鼠标操作(1)下载(2)上传2、通过命令操作rz、sz(1)下载sz(2)上传rz二、压缩、解压1、tar命令(1)压缩(2)解压2、zip命令压缩文件3、unzip命令解压文件一、上传、下载1、通过鼠标操作(1)下载将LInux系统中的文件下载到Windows上eg:在FinalShell......
  • AMD Zen5越来越近了!Linux GCC编译器已支持
    AMD预计会在今年年中左右开始推出下一代Zen5CPU架构产品,首先从移动端开始,然后是桌面端、服务器端,相关支持也正在紧锣密鼓地进行中,尤其是Linux系统下。现在,AMD已经将Zen5微架构加入到了GCC编译器的支持,GCCGit仓库的target设定值为“znver5”,可以赶上GCC4.1稳定版的发布。目前......
  • Linux操作系统小记
    1.finalshell使用Linux终端打开-输入ifconfig-查看ip地址finalshell-----SSH链接----输入信息2.Linux常用命令ls-a/      根目录隐藏文件ls-l/       竖着显示ls-lh/      竖着显示,并且包含大小pwd        ......
  • 【Linux】Linux系统(如CentOS)宝塔面板 如何安装SQL Server
    在Linux系统(如CentOS)上安装SQLServer是可能的,但是要注意,宝塔面板主要是用于管理Web服务器的,并不直接支持SQLServer的安装。SQLServer是微软开发的一款关系数据库管理系统,而宝塔面板通常用于管理类似于MySQL或MariaDB这样的数据库。不过,你可以在宝塔面板外部安装SQLServ......
  • Linuxcentos7配置网卡的方法(非gui篇)
    网卡配置方法有好几种,本次讲述的是非gui的centos7配置方法 目录 1、普通配置网卡方法: 2、使用命令行工具nmcli(NetworkManager的命令行界面)方法:删除连接:创建新的连接:注意事项:附记:  1、普通配置网卡方法:由于本次操作过程和我之前发布的文章的第一种原理......
  • Linux下的I/O多路复用
    在I/O多路复用中,epoll、poll和select是常用的三种机制,它们都可以用于实现事件驱动的网络编程。selectselect是Unix系统最早引入的I/O多路复用函数,它允许一个进程监视多个文件描述符,当其中任何一个文件描述符准备好进行I/O操作时,select函数就会返回。优点:跨平台支......