文件描述符(file descriptor)

本文主要介绍了Linux下的文件描述符。文件描述符fd是一个非负整数,是进程文件描述符表格数组的下标。每个进程有自己的PCB和文件描述符表格,默认0、1、2对应标准输入、输出和错误。用户通过系统调用打开或创建文件得到fd,OS会进行初始化并分配。关闭文件时内核会释放资源,fd还可与重定向联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在read();write();等对文件操作的这些系统调用中,我们会看到这样一个整数,fd(file descriptor),它就是文件描述符;

文件描述符到底是什么?

对于一个进程来说,它可以打开多个文件,而操作系统中又有多个进程,所以存在大量文件的打开与关闭,读与写....对于具体的一个进程而言,它打开的文件是需要组织的,操作系统承担了这一任务。

每个进程对应一个PCB块,在真正的代码里叫做struct task_struct{ };它们里面有一个结构体指针,指向一个指针数组,这个数组中每一个元素都是一个地址,是一个结构体的地址,具体而言:这个结构体描述的是文件( 操作系统规定,默认情况下,前三个地址分别是键盘,显示器,显示器的地址,分别称为标准输入,标准输出,标准错误),它们分别对应这个指针数组的下标是0 1 2;

【注】:Linux下所有的I/O设备都被抽象为文件,你要输出或者读入,其实是针对这些文件的读与写;

你要打开文件,你使用了系统调用open,你要创建文件,你使用create();

如上图,每一个进程都有自己的PCB,都有自己的文件描述符表格(也就是这个数组),而这个数数组的下标就是fd;

它是数组下标,那它的范围就是大于等于零,即非负;

对于一个进程来说,默认0 1 2已经有地址了,你再打开一个文件,fd对应就是3,即索引为3的指针数组元素存放了一个文件的地址,就是你打开的这个文件的地址;

【注】:文件在Linux中被抽象为struct file{};这样一个结构体,就连键盘,显示器这样的硬件也不例外,所谓一切皆文件;

我们提到的这个struct file{};这里面记录着被打开文件的所有信息,包括这个文件的inode,文件位置,打开模式....等信息;

用户使用系统调用 open ()或者 creat ()来打开或创建一个文件,用户态得到的结果值就是 fd;这个fd是怎么来的?OS在这个过程中做了什么?

它们的返回值就是fd(当然,如果有错误发生,就会返回-1);

值得注意的是:这个fd是就小分配的,OS会初始化这个文件的struct file{};在里面填入文件的inode以及打开模式,以及初始化这个文件的读写位置为0,最后在fd_array[ ]中填入地址,然后把fd返回给应用程序(即调用open/write的那个进程),你之后对于这个文件的所有操作,拿着这个fd来标识一个文件;

【关于就小分配】:比如你close(1);即你关闭了1号描述符,它本来对应标准输出到显示器,那么你再打开一个文件时,它的文件描述符就是1了,因为就小而言,0被标准输入占着;

有了这个文件描述符表,OS就明确知道哪个进程打开了哪些文件,有利于更好管理资源;

当你使用close();来关闭一个文件时,内核会释放上述数据结构,fd也将可以被其他文件分配;

当然一个进程退出时,它打开的所有文件(struct file{};fd....)占用的内存资源都会被释放;

写在最后:

这个文件描述符可以和重定向联系起来,例如dup2();等就是复制了指针数组的地址,从而索引对应下标时,地址不再指向原来的文件;

dup2将会拷贝oldfd为下标的地址到newfd的下标的地址;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值