FLOCK - Linux手册页

时间:2019-08-20 17:58:43  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2017-09-15

名称

flock-在打开的文件上应用或删除咨询锁

语法

#include <sys/file.h>
int flock(int fd, int operation);

说明

在fd指定的打开文件上应用或删除咨询锁。参数操作是以下之一:

LOCK_SH
放置一个共享锁。一个以上的进程可能会在给定的时间为给定的文件持有一个共享锁。
LOCK_EX
放置一个排他锁。在给定时间,只有一个进程可以为给定文件持有排他锁。
LOCK_UN
删除此过程持有的现有锁。

如果另一个进程持有不兼容的锁,则对flock()的调用可能会阻塞。要发出非阻塞请求,请在上述任何操作中包括LOCK_NB(通过ORing)。

单个文件可能不会同时具有共享锁和互斥锁。

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

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

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

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

无论文件打开的方式如何,都可以在文件上放置共享锁或排他锁。

返回值

成功时,返回零。如果出错,则返回-1,并正确设置errno。

错误说明

EBADF
fd不是打开的文件描述符。
EINTR
在等待获取锁的过程中,调用被处理程序捕获的信号传递中断;参见signal(7)。
EINVAL
操作无效。
ENOLCK
内核用完了用于分配锁定记录的内存。
EWOULDBLOCK
该文件被锁定,并选择了LOCK_NB标志。

遵循规范

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

备注

从内核2.0开始,flock()被单独实现为系统调用,而不是在GNU C库中作为对fcntl(2)的调用进行仿真。通过此实现,由flock()和fcntl(2)放置的锁定类型之间没有交互,并且flock()不会检测到死锁。 (但是请注意,在某些系统上,例如现代的BSD,flock()和fcntl(2)锁确实会彼此交互。)

flock()仅放置咨询锁;给定适当的文件权限,进程可以随意忽略flock()的使用并在文件上执行I / O。

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

不能保证转换锁(共享锁到互斥锁,反之亦然)是原子的:首先删除现有锁,然后再建立新锁。在这两个步骤之间,可能会批准另一个进程的未决锁定请求,结果是转换被阻止,或者如果指定了LOCK_NB则失败。 (这是原始的BSD行为,并且在许多其他实现中发生。)

NFS details

在2.6.11以下的Linux内核中,flock()不会通过NFS锁定文件(即,锁定范围仅限于本地系统)。取而代之的是,可以使用fcntl(2)字节范围锁定,该锁定确实可以在NFS上运行,因为给出了足够新的Linux版本和支持锁定的服务器。

从Linux 2.6.12开始,NFS客户端通过将flock()锁模拟为整个文件上的fcntl(2)字节范围锁来支持flock()锁。这意味着fcntl(2)和flock()锁确实通过NFS相互交互。这也意味着,为了放置排他锁,必须打开文件进行写入。

从Linux 2.6.37开始,内核支持兼容模式,该模式允许将flock()锁(以及fcntl(2)字节区域锁)视为本地模式。请参阅nfs(5)中有关local_lock选项的讨论。

另外参见

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

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

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/