flock(2) - Linux 手册页

名称

flock - 对打开的文件应用或移除建议锁

概要

#include <sys/file.h>

int flock(int fd, int operation);

描述

对由 fd 指定的打开文件应用或移除建议锁。参数 operation 是以下之一
LOCK_SH
放置一个共享锁。在给定文件和给定时间,多个进程可以持有共享锁。
LOCK_EX
放置一个独占锁。在给定文件和给定时间,只有一个进程可以持有独占锁。
LOCK_UN
移除此进程持有的现有锁。

如果另一个进程持有不兼容的锁,flock() 的调用可能会阻塞。要发出非阻塞请求,请将 LOCK_NB(通过 OR 运算)与上述任何操作结合使用。

单个文件不能同时具有共享锁和独占锁。

flock() 创建的锁与打开文件表条目关联。这意味着重复的文件描述符(例如,由 fork(2)dup(2) 创建的)引用相同的锁,并且可以使用这些描述符中的任何一个来修改或释放此锁。此外,锁可以通过任何这些重复描述符上的显式 LOCK_UN 操作释放,或者当所有这些描述符都已关闭时释放。

如果一个进程使用 open(2)(或类似函数)为同一个文件获得多个描述符,则 flock() 会独立地处理这些描述符。使用其中一个文件描述符尝试锁定文件可能会被调用进程通过另一个描述符已经放置的锁拒绝。

一个进程只能在一个文件上持有单一类型的锁(共享或独占)。对已经锁定的文件进行的后续 flock() 调用会将现有锁转换为新的锁模式。

flock() 创建的锁在 execve(2) 中会保留。

无论文件以何种模式打开,都可以对文件放置共享锁或独占锁。

返回值

成功时返回零。出错时返回 -1,并相应地设置 errno

错误

EBADF
fd 不是一个打开的文件描述符。
EINTR
在等待获取锁时,由于收到由处理程序捕获的信号而中断了调用;请参阅 signal(7)
EINVAL
operation 无效。
ENOLCK
内核分配锁记录的内存不足。
EWOULDBLOCK
文件已锁定且选择了 LOCK_NB 标志。

符合

4.4BSD(flock() 调用首次出现在 4.2BSD 中)。flock() 的一个版本,可能通过 fcntl(2) 实现,出现在大多数 UNIX 系统上。

说明

flock() 不在 NFS 上锁定文件。请使用 fcntl(2) 代替:在 Linux 的足够新版本和支持锁定的服务器上,它确实有效。

自内核 2.0 以来,flock() 作为自己的系统调用实现,而不是像在 GNU C 库中对 fcntl(2) 的模拟。这会产生真正的 BSD 语义:flock() 和 fcntl(2) 放置的锁类型之间没有交互,并且 flock() 不会检测死锁。

flock() 只放置建议锁;如果对文件具有适当的权限,则进程可以自由地忽略 flock() 的使用并在文件上执行 I/O。

flock() 和 fcntl(2) 锁对于派生进程和 dup(2) 具有不同的语义。在那些使用 fcntl(2) 实现 flock() 的系统上,flock() 的语义将与本手册页中描述的不同。

转换锁(从共享到独占,或反之)不能保证是原子的:现有锁首先被移除,然后建立一个新的锁。在这两个步骤之间,另一个进程的待处理锁请求可能会被授予,导致转换被阻塞,或者如果指定了 LOCK_NB 则转换失败。(这是原始 BSD 行为,并且发生在许多其他实现中。)

参见

flock(1), close(2), dup(2), execve(2), fcntl(2), fork(2), open(2), lockf(3)

Linux 内核源代码树中的 Documentation/filesystem/locks.txt(旧内核中的 Documentation/locks.txt

引用自

archivemail(1), chown(2), daemonize(1), dbopen(3), ddpt(8), explain(1), explain(3), explain_flock(3), explain_flock_or_die(3), flockfile(3), flopen(3), fstab-sync(8), getrlimit(2), halockrun(1), hylafax-server(5), lbdb_dotlock(1), lslk(8), nfs(5), perlfaq5(1), perlfunc(1), proc(5)