open函数的O_CREAT与O_EXCL

原创 2015年11月18日 21:32:35

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

linux下open函数和creat函数

open 函数用于打开和创建文件。以下是 open 函数的简单描述         #include fcntl.h>         int open(const char *path, int...
  • songyang516
  • songyang516
  • 2011年09月07日 22:37
  • 14457

Unix/Linux下的open函数(O_CREAT和O_EXCL)

今天想在Ubuntu上用open()实现检测文件是否存在,若存在就read()的功能,代码如下: int fd=open(temp,O_RDONLY|O_CREAT|O_EXCL,S_IRWXU...
  • abcd1f2
  • abcd1f2
  • 2015年11月13日 17:25
  • 694

带着O_CREAT和O_RDWR进入linux系统调用open函数

首先,linux内核的open函数是这么定义的SYSCALL_DEFINE3(open, ...),可以查到的宏定义为 #define SYSCALL_DEFINE3(name, ...) SYSC...
  • huoshanbaofa123
  • huoshanbaofa123
  • 2016年07月28日 19:26
  • 1410

open函数的flag详解

2.1.文件读写权限  (1)linux中文件有读写权限,我们在open打开文件时也可以附带一定的权限说明(譬如O_RDONLY就表示以只读方式打开,O_WRONLY表示以只写方式打开,O_RDWR...
  • qq_24373811
  • qq_24373811
  • 2016年08月22日 20:30
  • 357

open系统调用的O_CREAT和O_EXCL

O_CREAT               If the file does not exist, it will be created.  The owner (user ID) of the f...
  • ly890700
  • ly890700
  • 2016年11月06日 10:56
  • 221

linux 学习笔记(三):open、creat、close 函数的使用,文件的创建、打开与关闭

参考书籍:linux c编程实战  百度云下载链接: http://pan.baidu.com/s/1c2iD3X2 密码: wshq 自学中,看着这本书的pdf文件编程,由于之前学过c语言,所以c语...
  • shenhuaifeng
  • shenhuaifeng
  • 2016年05月24日 07:28
  • 4580

linux信号量简介(用户态)

一、说明     用户态进程使用的信号量又分为POSIX信号量和SYSTEM V信号量。POSIX信号量又分为有名信号量和无名信号量。有名信号量,其值保存在文件中, 所以它可以用于线程也可以用于进程间...
  • silent123go
  • silent123go
  • 2016年10月09日 09:26
  • 1042

fcntl.h头文件和unistd.h头文件

fcntl.h头文件和unistd.h头文件 转载地址:http://blog.sina.com.cn/s/blog_67eb1f2f0100m0sa.html fcntl.h定义了很多宏...
  • lyc_daniel
  • lyc_daniel
  • 2013年09月16日 16:55
  • 12689

细说linux IPC(九):posix消息队列

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途】         消息队列可以看作一系列消...
  • gentleliu
  • gentleliu
  • 2014年12月05日 16:45
  • 4083

JNI中新建文件、读写普通文件和驱动文件的方法综述fopen/open/creat/

这段时间的JNI开发中发现,在JNI中,普通文件的新建、读写既可以用C库函数,也可以用linux系统函数,如下: 平台android 4.4.2 编译工具ndk static int write...
  • luoyouren
  • luoyouren
  • 2015年11月11日 11:33
  • 2541
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:open函数的O_CREAT与O_EXCL
举报原因:
原因补充:

(最多只允许输入30个字)