UNIX系统支持在不同进程间共享打开的文件。

内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。

(1)每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:

(a)文件描述符标志(close_on_exec)。进程中每个打开描述符都有一个执行时关闭(close_on_exec)标志,若此标志设置,则在执行exec时关闭该描述符,否则该描述符仍打开。除非特地用fcntl设置了该标志,否则系统默认操作是在执行exec后仍保持该描述符打开。

(b)指向一个文件表项的指针。

(2)内核为所有打开文件维持一张文件表。每个文件表项包含:

(a)文件状态标志(读、写、添加、同步和非阻塞等)。

(b)当前文件偏移量。

(c)指向该文件v节点表项的指针。

(3)每个打开文件(或设备)都有一个v节点(v-node)结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针。对于大多数文件,v节点还包含了该文件的i节点(i-node,索引节点)。这些信息是在打开文件时从磁盘上读入内存的,所以所有关于文件的信息都是快速可供使用的。例如,i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件实际数据块在磁盘上所在位置的指针等。

注:Linux没有使用v节点,而是使用了通用i节点结构。虽然两种实现有所不同,但在概念上,v节点与i节点是一样的。两者都指向文件系统特有的i节点结构。

图3-1显示了一个进程的三张表之间的关系。该进程有两个不同的打开文件:一个文件打开为标准输入(文件描述符0),另一个打开文件为标准输出(文件描述符为1)。从UNIX系统的早期版本以来,这三张表之间的基本关系一直保持至今。这中安排对于在不同进程之间共享文件的方式非常重要。

创建v节点结构的目的是对在一个计算机系统上的多个文件系统类型提供支持。这一工作是由Peter Weinberger(贝尔实验室)和Bill Joy(Sun公司)分别独立完成的。Sun称此种文件系统为虚拟文件系统(Virtual File System),称与文件系统类型无关的i节点部分为v节点。

Linux没有将相关数据结构分为i节点和v节点,而是采用了一个独立与文件系统的i节点和一个依赖于文件系统的i节点。

如果两个独立进程各自打开了同一个文件,则有图3-2中所示的安排。我们假定第一个进程在文件描述符3上打开该文件,而另一个进程则在文件描述符4上打开该文件。打开该文件的每一个进程都得到一个文件表项,但对一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的理由是:这种安排使每个进程都有它自己的对该文件的当前偏移量。

  • 在完成每个write后,在文件表项中的当前文件偏移量即增加所写的字节数。如果这使当前文件偏移量超过了当前文件长度,则在i节点表项中的当前文件长度被设置为当前文件偏移量(也就是该文件加长了)。
  • 如果用O_APPEND标志打开了一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有添加标志的文件执行写操作时,在文件表项中的当前文件偏移量首先被设置为i节点表项中的文件长度。这就使得每次写的数据都添加到文件的当前尾端处。
  • 若一个文件用lseek定位到文件当前的尾端,则文件表项中的当前文件偏移量被设置为i节点表项中的当前文件长度。(注意,这与用O_APPEND标志打开文件是不同的。)
  • lseek函数只修改文件表项中的当前文件偏移量,没有进行任何I/O操作。

可能有多个文件描述符项指向同一个文件表项。例如,使用dup函数时。在fork后也会发生同样的情况,此时父、子进程对于每一个打开文件描述符共享同一个文件表项。

注意,文件描述符标志和文件状态标志在作用域方面的区别,前者只用于一个进程的一个描述符,而后者则适用于指向该给定文件表项的任何进程中的所有描述符。

关于文件描述符标志和文件状态标志的区别更直白的解释,可参考:http://blog.csdn.net/bayji/article/details/6020459

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

文件I/O(不带缓冲)之文件共享的更多相关文章

  1. 文件I/O(不带缓冲)之原子操作

    一.添写至一个文件 考虑一个进程,它要将数据添加到一个文件尾端.早期的UNIX系统并不支持open的O_APPEND选项,所以程序被编写成下列形式: ) < ) /* position to E ...

  2. 文件I/O(不带缓冲)概述

    一.引言 UNIX系统中大多数文件I/O只需用到5个函数:open.read.write.lseek以及close.这些函数经常被称为不带缓冲的I/O(unbuffered I/O).术语不带缓冲指的 ...

  3. UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O

    lienhua342014-08-25 1 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符. ...

  4. Unix文件 I/O(不带缓冲区的)上

    简介 Unix系统大多数文件i/o只需要:open.read.write.lseek.close这几个函数.但是某些时候我们也需要fcntl.ioctl.sync等函数配合使用.这些函数都是不带缓冲区 ...

  5. 带缓冲I/O和不带缓冲I/O的区别与联系

    转自:http://blog.csdn.net/lmh12506/article/details/6803847 首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用, ...

  6. 带缓冲的IO和不带缓冲的IO

    文件描述符: 文件描述符是一个小的非负整数,是内核用来标识特定进程正在访问的文件 标准输入/输出/出错: shell为每个程序打开了三个文件描述符,STDIN_FILEON,STDOUT_FILEON ...

  7. 带缓冲I/O 和不带缓冲I/O的区别与联系

    首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用.系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其 ...

  8. 第十三篇:带缓冲的IO( 标准IO库 )

    前言 在之前,学习了 read write 这样的不带缓冲IO函数. 而本文将讲解标准IO库中,带缓冲的IO函数. 为什么要有带缓冲IO函数 标准库提供的带缓冲IO函数是为了减少 read 和 wri ...

  9. Java 带缓冲的字节流和字符流

    输入流就是文件从硬盘到内存的中间媒介,那么输出流就是文件从内存到硬盘的中间媒介.首先来看看FileOutputStream的继承了哪些类, java.lang.Object java.io.Outpu ...

  10. 带缓冲的IO( 标准IO库 )

    前言 在之前,学习了 read write 这样的不带缓冲IO函数.而本文将讲解标准IO库中,带缓冲的IO函数. 为什么要有带缓冲IO函数 标准库提供的带缓冲IO函数是为了减少 read 和 writ ...

随机推荐

  1. codeforces 675D Tree Construction set

    转自:http://blog.csdn.net/qwb492859377/article/details/51447350 #include <stdio.h> #include < ...

  2. [irving] C# Windows Beep 调用声音文件

    方法一:Console.Beep(); 方法二:可以用Console.WriteLine("/a");来代替Beep(). MSDN:http://msdn.microsoft.c ...

  3. 新版本ubuntu13.10软件安装

    问题1:如何解决ubunt13.04不能和主机共享文件的问题 . 安装VMware Tools 网上有很多的资料,这里没有给出. . 设置共享文件夹目录 ) 在VMware虚拟机窗口,选择VM-> ...

  4. linux中的livecd、liveDVD和其他安装方式简介

    下载了几种不同格式的centos版本的iso文件,从而对比下各种iso文件的差别,下载的内容如下: 下载之后,分别在虚拟机中进行安装,从而查看有何区别: 1. 使用LiveCD进行安装 在选择安装介质 ...

  5. python中List的sort方法的用法

    python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...

  6. JavaScript中的事件冒泡机制

    事件冒泡机制 事件冒泡发生的条件:当为多个嵌套的元素设置了相同的事件处理程序,它们将触发事件冒泡机制.在事件冒泡中,最内部的元素将首先触发其事件,然后是栈内的下一个元素触发该事件,以此类推,直到到达最 ...

  7. 我用dedecms有感

    ---恢复内容开始--- 最近接了一个私单,简单的学校网站,注意,我一看上去是感觉很快,仿站,对方说这个东西你三天就能搞定啦,我也这么想的 (没经验啊) 接下来,我想都没想就用dedecms去做,之前 ...

  8. python和tk实现桌面番茄时间(1)

    参考资料: An Introduction To Tkinter Python 定时器 Python实例讲解 -- 定时播放 (闹钟+音乐) Python Tkinter之Label #coding= ...

  9. MUSIC算法学习笔记

    MUSIC即多重信号分类. MUSIC算法仅能估计非相干关信源,对相干信源,其性能将随信源间的相 关系数的增加而逐渐降低,直至完全恶化. 阵列信号处理的只要问题包括:波束形成技术,零点形成技术,空间谱 ...

  10. scanf,sscanf利用format跳过干扰的空格

    scanf,sscanf利用format跳过干扰的空格 用了一点时间做读取配置部分的代码,希望一次记录上读取N个数据, 希望读取的格式就是一个IP地址加上端口号,希望把IP地址读取到4个短整数里面,端 ...