想象一下,我有两个进程试图以只读模式打开同一个文件。我只希望一个进程打开文件,另一个进程失败(本质上是文件锁定)。做有什么区别
if (open("name", O_RDONLY | O_EXCL | O_NONBLOCK, 0666) == -1 && EWOULDBLOCK == errno) {
...
}
和
int fd = open("name", O_RDONLY | O_EXCL, 0666);
if (flock(fd, LOCK_EX | LOCK_NB, 0666) && EWOULDBLOCK == errno) {
...
}
是一样的吗?上述内容是否如我预期的那样有效?如果没有,那么O_EXCL该怎么办?有没有办法让上面的一个像我想要的那样工作?
正如问题 Erdal Küçük 在注释中交叉引用的O_EXCL写出的单词是什么所暗示(如果不是状态),O_EXCL
标志仅在您创建文件时才有意义。 您的其他open()
选项不会创建文件,因此使用O_EXCL
无关紧要(无害但无用)。 即使您正在创建文件,它也不会阻止另一个程序在创建文件后打开文件进行读取,而是在其他进程打开文件时。 请注意,如果另一个程序尝试使用O_EXCL
创建文件,那么另一个程序将无法创建文件 — 这就是O_EXCL
的用途。
您将需要使用一种咨询锁定机制 —flock(2)
(在 Linux 和 BSD 系统(可能还有其他系统)上找到,但未通过 POSIX 标准化),或 POSIX 函数lockf()
或fcntl()
.
访问该文件的所有程序都需要同意使用咨询锁定。 如果有人运行cat name
,cat
命令将不会注意文件name
上的咨询锁。
某些系统支持强制文件锁定。 如果支持,则通过在清除组执行位的同时在文件上设置 SGID 位来激活此功能。 如果系统支持强制文件锁定,则ls -l
可能会在组执行位列中列出l
;否则,它可能会报告S
。 因此,权限可能显示为以下任一:
-rw-r-lr--
-rw-r-Sr--
文件锁定功能不应与flockfile()
混淆,后者用于锁定多线程程序中的单个文件流,而不是用于锁定文件。