Unix系统编程()文件描述符和打开文件之间的关系

目前学习到的是一个文件描述符对应着一个打开的文件,似乎是一一对应的关系。但是实际上并不是这样的。多个文件描述符指向同一个打开的文件,是可能的也是必要的。这些文件描述符可以在相同或者不同的进程中打开。

要理解具体情况,需要查看内核维护的3个数据结构。

进程级的文件描述符表

系统级的打开文件表

文件系统的i-node表

针对每个进程,内核为其维护打开文件的描述符(open file descriptor)表。该表的每一条目都记录了单个文件描述符的相关信息。包括有一下信息:

控制文件描述符操作的一组标志。(目前,此类标志仅定义了一个,即close-on-exec标志)

打开文件句柄的引用

内核对所有打开的文件维护有一个系统级的描述符表格(open file description table)。有时也称之为打开文件表(open file table),并将表中各条目称之为打开文件句柄(open file handle)。一个打开文件句柄存储了一个与打开文件相关的全部信息,如下所示。

当前文件偏移量(调用read和write时更新,或者使用lseek直接修改)。

打开文件时所使用的的状态标志(即open的flags参数)

文件的访问模式(如调用open时所设置的只读模式,只写模式或读写模式)

与信息驱动IO相关的设置

对该文件i-node对象的引用。

每个文件系统都会为驻留其上的所有文件建立一个i-node表。以后将详细讨论i-node结构和文件系统的总体结构。每个文件的i-node信息,有以下:

文件类型(例如,常规文件、套接字或FIFO)和访问权限。

一个指针,指向该文件所持有的锁的列表。

文件的各种属性,包括文件大小以及与不同类型操作相关的时间戳。

此处将忽略i-node在磁盘和内存中的表示差异。磁盘上的i-node记录了文件的固有属性,诸如:文件类型、访问权限和时间戳。访问一个文件时,会在内存中为i-node创建一个副本,其中记录了引用该i-node的打开文件句柄数量以及i-node所在设备的主、从设备号,还包括一些打开文件时与文件相关的临时属性,例如:文件锁。

下图展示了文件描述符、打开的文件句柄以及i-node之间的关系。在下图中,两个进程拥有诸多打开的文件描述符。

在进程A中,文件描述符1和20都指向同一个打开的文件句柄(标号为23号)。这可能是通过调用dup、dup2或fcntl而形成的。

进程A的文件描述符2和进程B的文件描述符2都指向同一个打开的文件句柄(标号为73号)。这种情形可能在fork调用之后出现(即进程A和进程B是父子关系),或者当某进程通过UNIX套接字将一个打开的文件描述符传给另一个进程。

此外进程A的描述符0和进程B的描述符3分别指向不同的打开文件的句柄,但这些句柄均指向i-node表中的相同条目(1976),换言之,指向同一个文件。发生这种情况是因为每个进程各自对同一文件发起了open调用。同一个进程两次打开同一文件,也会发生这种情况。

结论:

两个不同的文件描述符,若指向同一个打开文件的句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量(由调用read、write或者lseek所致),那么从另一文件描述符中也会观察到这一变化。无论这两个文件描述符分别属于不同进程还是属于同一个进程,情况都是如此。

要获取和修改打开的文件标志(例如O_APPEND、O_NONBLOCK和O_ASYNC),可以执行fcntl的F_GETFL和F_SETFL操作,其对作用于的约束与上一条颇为类似。

相比之下,文件描述符标志(close-on-exec)为进程和描述符所私有。这一标志的修改不会影响同一个进程或不同进程中的其他文件描述符。

原文地址:https://www.cnblogs.com/tuhooo/p/8654740.html

时间: 2024-11-06 18:13:14

Unix系统编程()文件描述符和打开文件之间的关系的相关文章

Linux中文件描述符和打开文件之间的关系

Linux中文件描述符和打开文件之间的关系 文件描述符: 在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表. Linux中的文件类型 Linux系统中把一切都看做文件,包括普通文件-.目录文件d.字符设备文件c.块设备文件b.符号链接文件l.文件描述符是内核为了高效管理已被打开的文件所创建的索引(一个非负整数),用于指代已被打开的文件,Linux下所有的的I/O操作的系统调用都是通过文件描述符执行.例如0表示标准输入.1表示标准输出.3表示标准错

每天进步一点点——Linux中的文件描述符与打开文件之间的关系

转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符.程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误.如果此时去打开一个

Linux中的文件描述符与打开文件之间的关系

1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符.程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误.如果此时去打开一个新的文件,它的文件描述符会是3.POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号

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

转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html 简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp. open:文件描述符的操作(如: open)返回的是一个文件描述符(int fd),内核会在每个进程空间中维护一个文件描述符表, 所有打开的文件都将通过此表中的文件描述符来引用(fd1,fd2,fd3...); fopen:而流(如: f

文件描述符fd、文件指针fp和vfork()

1. fd:在形式上是一个非负整数.实际上他是一个索引值.指向kernal为每一个进程所维护的该进程打开文件的记录表. 当程序打开一个文件或者创建一个新文件的时候kernal向进程返回一个文件描述符. 优点:兼容POSIX标准,许多系统调用都依赖于它:缺点:不能移植到unix之外的系统上去 fp:FILE*指针变量标识符 优点:是C语言的通用格式,便于移植 2. vfork:使用方法同fork差不多,也适用于创建子进程 vofork特点: 1)在子进程调用exec或exit之前,它在父进程的空间

python 将文件描述符包装成文件对象

有一个对应于操作系统上一个已打开的I/O 通道(比如文件.管道.套接字等)的整型文件描述符,你想将它包装成一个更高层的Python 文件对象. 一个文件描述符和一个打开的普通文件是不一样的.文件描述符仅仅是一个由操作系统指定的整数,用来指代某个系统的I/O 通道.如果你碰巧有这么一个文件描述符,你可以通过使用open() 函数来将其包装为一个Python 的文件对象.仅仅只需要使用这个整数值的文件描述符作为第一个参数来代替文件名即可 import os fd = os.open('somefil

文件IO详解(二)---文件描述符(fd)和inode号的关系

1.文件描述符和inode号码是不同的两个东西. 2.对于每个进程,系统会建立一个进程控制块(PCB)来保存相关的信息,而这个PCB在内核中的表现其实就是一个称为task_struct的结构体,这个结构体的成员用来保存与此进程有关的相关信息,其中有个成员是struct file_struct  *files,它是用来找到此进程所有打开的文件列表的,files变量指向的是struct file_struct类型的结构体,这个结构体中有一个成员是一个指针数组struct file *fd_array

Unix文件系统学习笔记之二: 文件描述符、inode和打开文件表

Unix文件系统学习笔记之二: 文件描述符.inode和打开文件表 系统盘上数据的布局 文件系统无非是关于数据在磁盘上的组织以及存储空间管理的,为此,首先需要知道磁盘上数据的总体布局方式.以Unix为例,最重要的一张表如下: Unix 进程管理中和用户文件.io 最相关的数据结构:usr 数据结构 The procstructure does not record information related to file access.  However the userstructure con

TLPI(liunx/unix系统编程手册)笔记(四) 深入探究文件I/O

本章的重点我想就是原子操作,避免在几个进程在打开同一文件的时候造成的错误,了解一下时间片的概念会对本章有所帮助. (1)独占方式打开文件.(open     <-O_CREAT) 知道,open,可以创建文件并返回fd.当我们的进程运行到open这个函数时间片到了,另一个进程也对这个路径的文件open,那么时间片结束后两个进程都会认为自己是这个文件的拥有者.并未是独占创建打开的.在open 函数的第二个参数中有 O_EXCL 这种打开方式,可以解决独占的问题.另外可以在多进程对一个文件写的时候,