open函数的O_CREAT与O_EXCL

1. man解析

 O_EXCL 
 Ensure that this call creates the file: 
 if this flag is specified in conjunction with O_CREAT, 
 and pathname already exists, then open() will fail.

When these two flags are specified, symbolic links are not followed:
 if pathname is a symbolic link, then open() fails regardless of where the symbolic link points to.

In  general,  the  behavior  of  O_EXCL is undefined if it is used without O_CREAT.  
There is one exception: 
on Linux 2.6 and later, O_EXCL can be used without O_CREAT if pathname refers to a block device.  
If the block device is in use by the system (e.g., mounted), open() fails with the error EBUSY.

On NFS, O_EXCL is supported only when using NFSv3 or later on kernel 2.6 or later. 
In NFS environments where O_EXCL support is not provided, 
programs that rely on it for performing locking tasks  will  contain  a race  condition.   
Portable programs that want to perform atomic file locking using a lockfile, 
and need to avoid reliance on NFS support for O_EXCL, can create a unique file on the same filesystem
 (e.g., incorpo‐rating hostname and PID), and use link(2) to make a link to the lockfile. 
If link(2) returns 0, the lock is successful.  Otherwise, use stat(2) on the unique file to check 
if its link count has increased to 2, in which case the lock is also successful.

2. 用法

同时使用O_CREAT 和 O_EXCL 时,如果文件存在,就返回错误信息(open返回-1,errno是17 ‘EEXIST 17’)。
它可以测试文件是否存在。因为它是原子操作的。

设想这样一个需求:
某个任务要求只能单个进程执行,不能多个进程同时执行。
但实际上不能确保多个进程同时启动,尝试执行这个任务。
这样就进一步要求,只有第一个执行的进程可以继续,后续尝试执行的进程都报错退出。

方案之一就是使用带有O_EXCL标志的open()尝试打开一个文件。
第一个进程执行时文件并不存在,它能成功创建文件并继续执行。
第二个及后续的其它进程会因为文件已存在,从而open()失败,进程退出。

如果不使用O_EXCL标志,那你的代码可能要这样写:
if( access(file, R_OK) == -1 )
open(file, O_RDWR | O_CREAT,0666);

这个逻辑是有潜在的问题的,那就是判断文件是否存在与创建文件是两个独立的系统调用。
如果进程1执行access,判断出文件并不存在;
然后由于操作系统的调度策略,进程1暂停执行,进程2执行,进程2也会判断出文件不存在。

最终结果就是:两个进程调用open时都会成功,然后继续执行。这样就有多个进程同时执行这个任务。
因此使用方案一更好。
参考文献:
【1】 http://blog.csdn.net/season_hangzhou/article/details/8472430 作者:Season_hangzhou

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值