深入理解Linux文件描述符

news2024/11/28 10:53:30

>> Linux基础IO系列文章
1. Linux文件操作系统接口的学习使用

一、前言

 在上一篇博客中,我们初步学习了Linux文件操作的系统接口,不难发现的是,这些系统函数都与文件描述符密切相关:open函数返回值是一个文件描述符,write函数、read函数、close函数都是对于 文件描述符 进行操作。
在这里插入图片描述
 这让我们不禁思考,文件描述符到底是什么东西呢? 先上结论,文件描述符本质就是数组下标。此时的你肯定会有不少困惑,且看下文我为大家细细展开。

二、Linux标准文件描述符

[问题一]:为什么为什么打开文件时,fd总是从3开始? 0,1,2分别是什么?
image-20221103143600412

直接上结论:fd = 0~2的标准文件是默认被打开的,分别表示为

  • 0:标准输入 → 键盘
  • 1:标准输出 → 显示器
  • 2:标准错误 → 显示器

口说无凭,我们用代码来验证上面的结论:

  1. 从标准输入中直接读取数据
    image-20221103145021094
  2. 向标准输入中写入数据
    image-20221103145427113

[总结一]:

  1. fd = 0~2的文件分别对应着标准输入、标准输入和标准错误
  2. 标准文件是默认被打开的,因此 fd 总是会从3开始增加(除非手动关闭标准文件)

三、文件描述符与FILE结构体的关系

FILE是C语言定义的文件结构体,里面包含了各种文件信息。可以肯定的一点是,FILE结构体内一定封装了 fd 。为什么?来看接下来的思路分析:

1.使用系统接口的必然性
 文件存储在磁盘上,属于外设。谁有权限访问外设呢?只有操作系统。因为操作系统对上要提供稳定的服务,对下要管理好各种软硬件资源
 如果文件操作能绕开操作系统,那么操作系统怎么知道某个文件到底有没有被创建,有没有被销毁呢,还怎么给你提供稳定的服务呢?基于上述简单的认识,我们不难理解,要想访问硬件资源,就必须通过操作系统
 而操作系统出于安全性和减少使用成本的角度考虑,是不相信任何人的。就像银行一样,不会将金库直接向大众开放,而是只会有几个业务窗口为大家提供服务。操作系统也是这样,操作系统提供的窗口就是系统接口。
 至此通过我们的逻辑推演,我们已经可以得出以下的结论:要想访问外设就必须使用操作系统提供的系统接口。所以C语言的各种文件操作函数本质就是对系统接口的封装

2.FILE结构体封装fd的必然性
 C语言的文件操作都是系统统接口的封装,而系统接口的使用只认fd,因此FILE结构体中必然会封装fd

​ 验证的方法也很简单直接:

image-20221103151323233

四、进程与文件的映射关系

在理解两者的关系之前,我们首先来回答几个问题,让大家有基础的认识:

[问题二]:打开的本质是什么?
 答:本质是将文件加载到内存。为什么要加载到内存?这是由冯诺依曼体系决定的

[问题三]:打开文件、访问文件、关闭文件,都是谁在操作?
 答:这些操作都是我们调用函数完成的,难道说是我们操作的吗?哈哈这样想就单纯了。当我们编译生成可执行文件的时候,有进行文件操作吗?答案显然是没有。我们的程序文件只有在运行起来的时候才会执行相应的代码,然后才会执行相应的文件操作。所以说这些操作本质都会由进程完成的。所以文件操作本质上是进程和打开的文件的联系

[问题四]:OS如何管理大量的文件呢?
 答:当文件被打开时,文件是存在于内存中的,因此内存中当然会存在大量的文件。操作系统要不要管理这些文件呢?答案是肯定的。如何管理呢?显然是是先描述后组织的设计思想:
 一个文件被打开,在内核中就要创建对应的内核数据结构struct file(先描述),然后通过链表的方式将各个文件组织起来(后组织)。伪代码形式如下:

struct file
{
   // 文件内容和属性成员变量
   struct file* next;
   struct file* prev;
}

 有了上述的基本认识之后,我们基于Linux 内核源码,再来具体谈谈进程与文件的映射关系:

 进程控制块 task_struct 中有一个类型为 files_struct 的文件指针,files _struct
在这里插入图片描述
在这里插入图片描述
 在 files_struct 有一个成员类型为 file* 的指针数组,数组中的每个指针变量就对应着被该进程打开的文件。所以 fd 本质上就是 fd_array 数组的下标 file*结构体表示文件的各种基本信息。
 在用这样一张图来为大家梳理思路:
在这里插入图片描述

[问题五]:文件描述符的分配规则
 答:从头遍历fd_arr数组,找到一个最小的没有被使用的下标,分配新的文件。如果我们手动将 fd = 1 的文件关闭,那么新创建文件的 fd 就等于1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python编程挑战赛

题1:给小朋友分糖,每人分到糖的数量不同,输入小朋友的数量,计算至少需要多少糖? 思路:第1个小朋友1颗糖,第2个小朋友2颗糖,第3个小朋友3颗糖,……第n个小朋友n颗糖&#…

[数据结构]实现双向链表

作者: 华丞臧. 专栏:【数据结构】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 文章目录一、带头双向循环链表二、带头双向循环链表接口实现2.1 双向链表的初始化、打…

动态规划算法的题到底应该怎么做?思路教给你自己写

本文是我通过做题和借鉴一些前人总结的套路而得出的思路和方法,刚好这次CSDN第八周的周赛上出了三道动态规划的题目,我会结合题目对我的思路进行一个输出,会从最简单的一维dp开始讲解到二维dp,希望对你有帮助,有错误希…

MySQL数据库基础知识

今天是更新数据库的第一篇,关于数据库环境搭建问题博主先不在这里介绍了,博主今天是直接讲知识了,等以后的博客,博主再更新数据库搭建问题。在这里我们使用命令行式客户端,先不使用windows下的图形化界面,使…

ReadingTime-十一月

CV文章浅读_not_everday0x1105.CAViT for video object re-id 2022_中科院这个月主要是要学习pytorch和一些CV baseline的复现,搞搞毕设雏形🆙 以后还是把笔记写纸上要么写博客,不放本地了😨 网页版小绿鲸zen好用 😃 …

峰会实录 | 基于StarRocks和腾讯云EMR构建云上Lakehouse

作者:腾讯云EMR业务负责人陈龙(本文为作者在 StarRocks Summit Asia 2022 上的分享) 我目前负责腾讯云EMR 的研发工作,此前先后在百度、支付宝做后端研发。2011年加入腾讯,先后参与了腾讯云Redis、腾讯云云数据库、Ap…

小米 Civi 2 (ziyi) 机型解锁bl 获取root权限教程 +其他机型参数对比+救砖

*********机型优点与其他机型参数对比***************** 小米 Civi 2 (ziyi) 国行版机型前置由3200万主摄3200万超广角组成的双摄是它最大的亮点,配有4颗柔光灯。自拍相当不错。他的后置主摄采用5000万像素相机,IMX766传感器,1/1.56英寸感光…

【MybatisPlus】CRUD操作,映射匹配兼容性,ID生成策略,逻辑删除,乐观锁

文章目录MybatisPlus简介一、数据层基本的开发1. 引入jar包2. 配置数据源3. 编写实体类4. 创建Dao接口5. 测试二、CRUD使用1. 查询2. 添加3. 删除4. 修改5. 分页查询三、条件查询1. 条件查询的方式2. 多条件查询四、映射匹配兼容性1. 表字段与编码属性设计不同步2. 编码中添加了…

矩阵理论复习(二)

内积空间的定义 模与内积 向量x和y的夹角 正交向量、正交组和正交矩阵 度量矩阵 基向量内积、度量矩阵、任意向量内积之间的关系 欧式空间的两个基对应的度量矩阵彼此合同 度量矩阵的行列式的几何问题 正交补子空间 内积空间子空间U与U的正交补子空间的直和 …

LeetCode 138. 复制带随机指针的链表

难度 中等 题目链接 示例: 解题思路: 首先,大家肯定会这样想:定义一个cur循环遍历,每次遍历一个,就malloc一个。 当遍历后面的时候,就开始尾插。 但现在有一个问题是:这个random指…

通信直放站基础知识

直放站的定义 直放站(中继器)属于同频放大设备,是指在无线通信传输过程中起到信号增强的一种无线电发射中转设备。直放站的基本功能就是一个射频信号功率增强器。直放站在下行链路中,由施主天线从现有的覆盖区域中拾取信号&#x…

《嵌入式 - 嵌入式大杂烩》CoreMark性能测试

1 CoreMark简介 CoreMark是由EEMBC(Embedded Microprocessor Benchmark Consortium)的Shay Gla-On于2009年提出的一项基准测试程序,CoreMark的主要目标是简化操作,并提供一套测试单核处理器核心的方法。测试标准是在配置参数的组合下单位时间内运行的Co…

【树莓派不吃灰系列】快速导航

目录1. 通用篇2. Python篇3. 编程IO篇❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2022-11-06 ❤️❤️ 本篇更新记录 2022-11-06 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言 📝&…

Slave_IO_Running: No 的解决

原因: 两台主从数据库的uuid相同了(没猜错的话,各位的第二台虚拟机都是克隆了第一台,然后就改了个ip对吧)。 解决办法: 必须跟着步骤来,一步也不能多,更不能少,请仔细…

arcgis 生成切片并发布服务

需要准备: 1、需要进行切割的tif文件; 2、切片方案文件 需要确认: 1、tif文件的数据源坐标系; 2、现有切片方案能否满足需求; 3、部署的地图引擎是经纬度投影还是墨卡托投影; 具体操作流程: 1…

TCP/IP协议数据链路层

目录 一、数据链路层和网络层的关系 二、以太网 1、以太网格式 2、认识MTU 三、ARP协议 1、ARP协议的作用 2、ARP协议的工作流程 3、ARP数据报的格式 4、思考:浏览器中输入url后, 发生的事情(经典面试题) 一、数据链路层和网络层的…

通信行业的必备网站

今天突然看到一首诗感触满满: 官策作者陈京 生如蝼蚁,当有鸿鹄之志! 命如纸薄,应有不屈之心! 大丈夫生于天地间,岂能郁郁久居人下。 当以梦为马,不负韶华。 乾坤未定,你我皆是黑马&…

西安交大讲座-实际场景(3个)出发,用户检测方式,数据驱动的网络用户行为分析建模与异常检测

讲座搬运,侵删! 目录 研究背景 研究问题 问题与挑战 网络舆情分析 政策法规知识图谱 构建利益方群体识别模型 系统 ​编辑 第二个工作-异常群体映射与定位 多源社交网络用户身份管理 不用场景的用户身份映射 多个平台关联 黑产检测 基于图模型…

基于FreeCAD的dxf转机械手代码的一种实现方法

dxf文件在2D图形中使用广泛,将图形文件自动转换为机械手可识别的轨迹代码是机械手全自动化中一个软件衔接节点。理想的轨迹自动化转换程序可以在电脑里面直接虚拟仿真生成机械手轨迹,简化现场人员机械手示教流程,在效率和远程支持上有着实际的…

2021 神经网络压缩 (李宏毅

首先,为什么需要对神经网络模型进行压缩呢?我们在之前的课程中介绍过很多大型的深度学习模型,但当我们想要将这些大模型放在算力比较小的边缘设备或者其他IoT设备里面,就需要对大模型进行压缩。 Lower latency:低时延 …