文件共享

UNIX系统支持在不同进程中共享打开的文件,首先先用一幅apue的图来介绍一下内核用于I/O文件的数据结构:

如图所见,一个进程都会有一个记录项,记录项中包含有一张打开文件描述符表,每个描述符占用一项。

描述符包括:(a)文件描述符标志(fd标志),(b)指向一个文件表项的指针(文件指针)。

而文件表包括:(a)文件状态标志,(b)当前文件偏移量,(c)v节点指针

v节点包括:文件类型和对此文件进行各种操作的函数的指针,大部分v节点还包括年i节点(索引节点,第四章详细介绍)

如果两个进程各自打开同一个文件的话,文件表是的分开的,但v节点是共享的:

文件表分开是因为:使每个进程都有它自己的对该文件的当前文件偏移量。

这样,当多个进程写同一个文件时,就有可能出问题。Let me tell you why.

早期的UNIX没有O_APPEND追尾选项,所以写到文件的结尾是这样做的:

if (lseek(fd, 0L, 2) < 0) /* 定位到文件的末端 */

err_sys("lseek error");

if (write(fd, buf, 100) != 100) /* 追尾写100字节 */

err_sys("write error");

这样对单个进程来说是没有问题的。但是对于多个进程对同一个文件同时使用这种方法就会出错了。

比如A和B进程同时打开一个文件,假定A调用了lseek,它将进程A的该文件当前偏移量设置为1500字节(文件末尾处),然后内核切换B进程运行,B也是调用lseek也将该文件的当前偏移量设置为1500字节(文件末尾处,记住,每个进程并不是共享同一个当前文件偏移量的),然后B调用了write函数,将当前偏移量曾至1600字节。因为该文件的长度已经增加了,所以内核对v节点中的当前文件长度更新为1600。然后内核切回A进程,当A调用write时,就从当前文件偏移量(1500字节)处将数据写到文件中去,这样也就代换了进程B
刚写到该文件中的数据。

问题出在逻辑操作“先定位到文件尾端处,然后写“上,它使用了两个分开的函数调用。解决的方法就是使这两个操作变成一个操作(这也就叫做原子操作)。任何一个需要多个函数的操作都不可能是原子操作,因为在两个函数调用之间,内核都有可能临时挂起该进程(如上面所加假定的)。

UNIX提供了一种方法使这种操作成为原子操作,该方法就是在打开文件时设置O_APPEND标志。这就使内核每次对这种文件进行写之前,都将进程的当前文件偏移量设置到该文件的尾端处,于是每次写之前就不用再调用lseek。

一般而言,原子操作(atomic operation)指的时由多步组成的操作。如果该原子操作执行,则要么时执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。(只要理解原子是不可分的就行了)

第三章笔记待续。

《APUE》第三章笔记(3)的更多相关文章

  1. 《APUE》第三章笔记(2)

    read函数 调用read函数从打开的文件中读数据. #include <unistd.h> ssize_t read(int filedes, void *buf, size_t nby ...

  2. 《APUE》第三章笔记(1)

    以下内容是我看<APUE>第二版第三章的笔记,有错还希望指出来,谢谢. unbuffered I/O,跟buffered I/O相对,buffered I/O就是 ISO C标准下的标准输 ...

  3. 【转】《APUE》第三章笔记(4)及习题3-2

    原文网址:http://www.cnblogs.com/fusae-blog/p/4256794.html APUE第三章的最后面给出的函数,现在还用不着,所以,先留个名字,待到时候用着了再补上好了. ...

  4. 《APUE》第三章笔记(4)及习题3-2

    APUE第三章的最后面给出的函数,现在还用不着,所以,先留个名字,待到时候用着了再补上好了. dup和dup2函数:用来复制文件描述符的 sync函数,fsync函数和fdatasync函数:大致的功 ...

  5. HBase in Action前三章笔记

    近期接触HBase,看了HBase In Action的英文版.開始认为还行,做了些笔记.可是兴许看下去,越来越感觉到实战这本书比較偏使用上的细节,对于HBase的具体设计涉及得很少.把前三章的一些笔 ...

  6. 《HALCON数字图像处理》第三章笔记

    目录 第三章 HALCON图像处理基础 HALCON控制语句 HALCON算子 HALCON图像处理入门 HALCON图像读取 HALCON图像显示 图形窗口 图像显示 显示文字 HALCON图像转换 ...

  7. [ APUE ] 第三章 文件系统

    1. 文件描述符 打开或创建一个文件时,内核向进程返回一个文件描述符,当读.写一个文件时,用open()或creat()返回的文件描述符标识该文件,将其作为参数传递给write.read. stdin ...

  8. unix环境高级编程第三章笔记

    文件描述符 1.文件描述符的概念 对于内核而言,所有打开的文件都会用一个文件描述符来引用,打开或和创建一个新文件的时候,内核会给进程返回一个文件描述符,而当使用read write时,可以使用这个文件 ...

  9. Vue2.5开发去哪儿网App 第三章笔记 上

    1.  vue 生命周期函数 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 ...

随机推荐

  1. 为什么 var_dump("1" == "1e0"); 的结果为true

    今天,同学问我一个问题,如下:var_dump("1" == "1e0"); 的结果是什么. 我的第一反应,答案是false.因为很明显的要比较的是两个字符串, ...

  2. Cocos2d-x创建新工程

    转自:http://www.cnblogs.com/andyque/archive/2011/09/27/2192920.html 而是新建一个工程.然后,我们不是copy文件夹.lib和dll了.我 ...

  3. 基于Cloudera Manager5配置HIVE压缩

    [Author]: kwu 基于Cloudera Manager5配置HIVE压缩,配置HIVE的压缩.实际就是配置MapReduce的压缩,包含执行结果及中间结果的压缩. 1.基于HIVE命令行的配 ...

  4. Drawable、Bitmap、byte[]之间的转换

    android在处理一写图片资源的时候,会进行一些类型的转换: 1 Drawable → Bitmap 的简单方法 ((BitmapDrawable)res.getDrawable(R.drawabl ...

  5. .ssh 文件夹权限设置问题

    .ssh 文件夹权限 问题 今天遇到了 关于.ssh 文件夹夹 设置什么权限合适问题 :答案是 700 chmod 700 .ssh

  6. IIS7及以上伪静态报错404

    内容摘要:故障现象:DTCMS开启伪静态功能,VS2010预览正常,发布到IIS后报错404.0错误(WIN7,WIN8,SERVER2008).模块IISWebCore通知MapRequestHan ...

  7. VOA学习-South Sudan Must Allow Aid

    South Sudan Must Allow Aid The United States is gravelyconcerned by the serious escalation of the hu ...

  8. 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作

    ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...

  9. [整理]Oracle LOCK 机制

    数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.锁机制用于管理对 ...

  10. 学点css之经验总结篇章

    学css说起来应该有三天左右的时间的,加上之前了解的基础,对css有一点的感性认识了,相应代码有有比较好的把握,现在就通过分享几张照片的形式分享一下我的收获 备注:在Border的外边的部门被称作:o ...