简介Linux下的文件描述符

在C程序中,文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文 件描述符。下面重点来说下,文件描述符是如何工作的。

文件描述符相当于一个逻辑句柄,而 open,close等函数则是将文件或者物理设备与句柄相关联。句柄是一个整数,可以理解为进程特定的文件描述 符表的 索引。先介绍下面三个概念,后面讲下open、close等操作以后,文件和文件描述符产生什么关系,以 及fork后文件描述符的继承等问题。

文件描述符表:用户区的一部分,除非通过使用文件描述符的函 数,否则程序无法对其进行访问。对进程中每个打开的文件,文件描述符表都包含一个条目。

系统文件表 :为系统中所有的进程共享。对每个活动的open, 它都包含一个条目。每个系统文件表的条目都包含文件偏移 量、访问模式(读、写、or 读-写)以及指向它的文件描述符表的条目计数。

内存索引节点表: 对系统中 的每个活动的文件(被某个进程打开了),内存中索引节点表都包含一个条目。几个系统文件表条目可能对应 于同一个内存索引节点表(不同进程打开同一个文件)。

1、举例: 执行myfd = open( "/home/lucy/my.dat", O_RDONLY); 以后,上述3个表的关系原理图如下:

系统文件表包含 一个偏移量,给出了文件当前的位置。若2个进程同时打开一个文件(如上图A,B)做读操作,每个进程都有自 己相对于文件的偏移量,而且读入 整个文件是独立于另一个进程的;如果2个进程打开同一个文件做写操作, 写操作是相互独立的,每个进程都可以重写另一个进程写入的内容。

如果上面进程在open以后又执行了 close()函数,操作系统会删除文件描述符表的第四个条目和系统文件表的对应条目(若指向它的描述符表 唯一), 并对内存索引节点表条目中的计数减1,如果自减以后变为0,说明没有其他进程链接此文件,将索 引节点表条目也删除,而这里进程B也在open这个文件,所 以索引节点表条目保留。

2、文件描述符 的继承

通过fork()创建子进程时,子进程继承父进程环境和上下文的大部分内容的拷贝,其中就包括文 件描述符表。

(1)对于父进程在fork()之前打开的文件来说,子进程都会继承,与父进程共享相同的文 件偏移量。如下图所示(0-1-2 表示 标准输入-输出-错误):

系统文件表位于系统空间中,不会被 fork()复制,但是系统文件表中的条目会保存指向它的文件描述符表的计数,fork()时需要对这个计数进行维 护, 以体现子进程对应的新的文件描述符表也指向它。程序关闭文件时,也是将系统文件表条目内部的计数 减一,当计数值减为0时,才将其删除。

(2)相反,如果父进程先进程fork,再打开my.dat,这时父子进 程关于my.dat 的文件描述符表指向不同的系统文件表条目,也不再共享文件偏移量(fork以后2个进程分别 open,在系统文件表中创建2个条目);但是关于标准输入, 标准输出,标准错误,父子进程还是共享的。

时间: 2024-08-03 19:57:27

简介Linux下的文件描述符的相关文章

Linux下利用文件描述符恢复的成功失败实验

    数据误删除是作为初级运维人员常常遇到的"低级错误",一些有经验的老手有时也在疲劳.不冷静的情况下"马失前蹄".一旦误删除数据文件,尽快采用影响最小.最迅速的手段恢复数据库是第一要务. 恢复数据的方法很多,比如冷热备份.闪回数据库等等,如果是直接从操作系统OS层面删除数据文件,在Linux/Unix环境下,有一些优选手段可以使用.其中之一就是文件描述符(File Description).   1.聊聊File Description   不同的操作系统,在实

linux exec和文件描述符妙用技巧(转)

  最近在看<精通unix shell脚本编程>时,看到exec<$1 exec 1>$OUTFILE,一下看的我就蒙了.网上看了大半天,终于搞定,记录如下.对于 Linux 而言,所有对设备和文件的操作都使用文件描述符来进行的.文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程打开文件的记录表.当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数.通常,一个进程启动时,都会打开 3 个文件

使用LINUX dup2 复制文件描述符到标准输出STDOUT_FILENO

  7    8 #include<stdio.h>   9 #include <sys/types.h>  10 #include <sys/stat.h>  11 #include <fcntl.h>  12 #include <stdlib.h>  13 #include <unistd.h>  14   15   16   17 int main(int argc,char *argv[])  18 {  19     int

更改linux的最大文件描述符限制

To ensure good server performance, the total number of client connections, database files, and log files must not exceed the maximum file descriptor limit on the operating system (ulimit -n). By default, the directory server allows an unlimited numbe

[性能分析]linux文件描述符(转)

1.什么是文件和文件描述符   Linux中文件可以分为4种:普通文件.目录文件.链接文件和设备文件.1.普通文件是用户日常使用最多的文件,包括文本文件.shell脚本.二进制的可执行和各种类型的数据.ls -lh 来查看某个文件的属性,可以看到有类似 -rw-r--r-- ,值得注意的是第一个符号是 - ,这样的文件在Linux中就是普通文件.这些文件一般是用一些相关的应用程序创建,比如图像工具.文档工具.归档工具... .... 或 cp工具等.这类文件的删除方式是用rm 命令:2.目录文件

文件句柄(file handles) &amp;amp; 文件描述符(file descriptors)

1.概述 在实际工作中会经常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如报错: too many open files, 如果你对相关知识一无所知,那么debug起来将会异常痛苦.在linux操作系统中,文件句柄(包括Socket句柄).打开文件.文件指针.文件描述符的概念比较绕,而且windows的文件句柄又与此有何关联和区别?这一系列的问题是我们不得不面对的. 博主通过翻阅相关资料,并采用了一些demo来验证相关观点.如果文中有理解偏差,欢迎指正,对linux内核不是很熟,

并发时-修改Linux系统下的最大文件描述符限制

通常我们通过终端连接到linux系统后执行ulimit -n 命令可以看到本次登录的session其文件描述符的限制,如下: $ulimit -n 1024 当然可以通过ulimit -SHn 102400 命令来修改该限制,但这个变更只对当前的session有效,当断开连接重新连接后更改就失效了. 如果想永久变更需要修改/etc/security/limits.conf 文件,如下: vi /etc/security/limits.conf * hard nofile 102400 * sof

Linux内核中的文件描述符

Kernel version:2.6.14 CPU architecture:ARM920T 作为文件的使用者,进程理所当然的要将所使用的文件记录于自己的控制块中,也就是task_struct.另外,由于进程所对应的程序也是一个文件,因此进程控制块还必须记录这个文件的相关信息.由于OS要对所有进程提供服务,因此OS还要维护一个记录所有进程打开的文件的总表. 1.文件对象 当进程通过open系统调用打开一个文件时,该系统调用找到这个文件后,会把文件封装到一个file结构的实例中提供给进程,这个实例

linux中文件描述符fd和文件指针flip的理解

整理自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html 简单归纳:fd(file descriptor)只是一个整数,在open时产生.起到一个索引的作用.每个进程在PCB(Process Control Block)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp. 文件描述符的操作(如: