zoukankan      html  css  js  c++  java
  • Unix系统编程()原子操作和竞争条件

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

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

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

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

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

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

    但有个情况是:

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

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

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

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

    image

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

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

    向文件尾部追加数据

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

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

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

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

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

  • 相关阅读:
    表相关操作
    表的约束
    windows平台MySQL安装
    网络编程2
    Python元类
    并发编程这个只是占位使用而已
    并发编程2
    并发编程1
    Mac装机神器Homebrew
    基于Django框架开发BBS项目
  • 原文地址:https://www.cnblogs.com/tuhooo/p/8643916.html
Copyright © 2011-2022 走看看