竞争状态是这样一种情形:操作共享资源的两个进程(或线程),其结果取决于一个无法预期的顺序,即这些进程获得CPU使用权的先后相对顺序。

以独占的方式创建一个文件

当同时指定了O_EXCL和O_CREAT作为open的标志位时,如果要打开的文件已经存在,则open将返回一个错误。

这种机制为了保证进程是打开文件的创建者。

对文件是否存在的检查和创建属于同一原子操作。、

如果不实用O_EXCL标志的话,要调用两次open,以此判断文件是否存在,一个是创建一个文件。

但有个情况是:

当第一次调用open时,希望打开的文件还不存在,而当第二次调用open时,其他进程已经创建了该文件。

如下图,若内核调度器判断出分配给A进程的时间片已经耗尽,并且将CPU的使用权交给B进程,就有肯能发生这种问题。

再比如两个进程在一个多CPU系统上同时运行,也会出现这种情况。

在这种情况下,A会认为目标文件是由自己创建的。因为不论目标文件存在与否,进程A对open的第二次调用都会成功。

由于第一个进程在检查文件是否存在和创建文件之间发生了中断,造成两个进程都声称自己是文件的创建者。

结合O_CREAT和O_EXCL标志来一次性地调用open可以防止这种情况,因为这确保了检查和创建文件的捕捉属于一个单一的原子(不可中断的)操作。

向文件尾部追加数据

说明原子操作的第二个例子是:多个进程文件同时同一个文件(例如,全局日志文件)尾部添加数据。

每次写入新的日志时,会用lseek将文件偏移量设置到文件尾部,然后再写入数据。

但是在lseek和write之间会被其他进程所打断,那么这两个进程在写入数据前,将文件偏移量设为相同位置,而当第一个进程再次获得调度时,会覆盖第二个进程已写入的数据。此时再次出现了竞争状态,因为执行的结果依赖于内核对两个进程的调度顺序。

要规避这一个问题,需要将文件偏移量的移动与数据写入操作纳入同一个原子操作。在打开文件时加入O_APPEND标志就可以保证这一点。

注意了,在打开文件时加入O_APPEND标志。所以这个意思就是,打开之后的写都是先移到文件末尾,在写数据咯?

Unix系统编程()原子操作和竞争条件的更多相关文章

  1. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

  2. 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll

    关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...

  3. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  4. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  5. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  6. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  7. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  8. 《Linux/Unix系统编程手册》读书笔记5

    <Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...

  9. 《Linux/Unix系统编程手册》读书笔记4

    <Linux/Unix系统编程手册>读书笔记 目录 第7章: 内存分配 通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存. 基本学过C语言的都用过mallo ...

  10. 《Linux/Unix系统编程手册》读书笔记3

    <Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...

随机推荐

  1. 【转】svn 的开发目录结构和流程

    原文: https://blog.csdn.net/iteye_15570/article/details/82548132 ------------------------------------- ...

  2. tomcat生产部署关键參数设置

    JVM设置 个节点.每一个tomcat估计处理500个链接,那么连接池的长连接数最大设为2000. 全节点复制(DeltaManager)模式集群节点数3-6为宜. 主备复制(BackupMnagag ...

  3. redhat下安装mysql 5.6.20,解压zip包,查看已经安装过的mysql,卸载rpm安装包,安装mysqlserver端和client,改动mysqlusername,登陆mysql,启动关闭mysql

     1 将相关的mysql rpm包上传到redhat上 2  我的电脑是Redhat 6.*版本号.所以这里使用上面一个 3  解压zip包 4  安装下面几个rpm MySQL-client-a ...

  4. ASP.NET找不到类型或命名空间名称怎么办

    如图所示,运行之后提示找不到类型或空间名称,右击有波浪线的代码,选择解析,using XXX   随后自动补上了程序集引用

  5. JQMobile引入外部CSS,JS文件

    使用CDN <!DOCTYPE html> <html> <head> <title>html5</title> <meta name ...

  6. UNIX网络编程读书笔记:端口号、套接口对和套接口

    端口号 端口号(port number):16位整数,用来区分不同的进程. 服务器使用的端口号:TCP和UDP定义了一组众所周知的端口(well-known port),用于标识众所周知的服务. 客户 ...

  7. jvm分析备忘

    是什么 jps   查看所有的jvm进程,包括进程ID,进程启动的路径等等. jstack   观察jvm中当前所有线程的运行情况和线程当前状态. 系统崩溃了?如果java程序崩溃生成core文件,j ...

  8. Linux下挂载硬盘分区的几种方法

    1.使用Autofs自动挂载分区 2.修改/etc/fstab 3.编写shell脚本,开机自动运行mount命令  方法一.使用Autofs  1.Autofs的特点:Autofs与Mount/Um ...

  9. 利用pandas进行数据分析之二:DataFrame与Series数据结构对比

    Series与DataFrame对比学习 文章为本人原创,未经同意请勿转载,http://www.cnblogs.com/smallcrystal/ Series:构建的方法,一组数组(列表或元组), ...

  10. NuGet学习笔记(2) 使用图形化界面打包自己的类库[转]

    http://www.cnblogs.com/lzrabbit/archive/2012/05/01/2477607.html 上文NuGet学习笔记(1) 初识NuGet及快速安装使用说到NuGet ...