我在stackerflow上读了足够多关于flock
/lockf
/fcntl
之间差异的帖子,但我无法回答以下观察结果:
>>> import fcntl
>>> a = open('/tmp/locktest', 'w')
>>> b = open('/tmp/locktest', 'w')
>>> fcntl.lockf(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.lockf(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.lockf(b, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>>
>>> a.close()
>>> b.close()
>>> a = open('/tmp/locktest', 'w')
>>> b = open('/tmp/locktest', 'w')
>>> fcntl.flock(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.flock(a, fcntl.LOCK_EX | fcntl.LOCK_NB)
>>> fcntl.flock(b, fcntl.LOCK_EX | fcntl.LOCK_NB)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 35] Resource temporarily unavailable
为什么这两种情况下的行为不同?我知道一个显而易见的答案,那就是这是两种不同的锁定机制。我正在寻找:
lockf()
或flock()
对文件(inode/fd
)究竟做了什么- 根据演示,我们可以递归地使用相同的锁吗
我了解fds
的基本知识,所以我更希望得到一个对操作系统级细节有更多见解的技术答案。
OSX 10.9.3,Python:2.7.5
一篇关于这方面的好文章:关于文件锁定的Brokeness
简而言之:
-
POSIX锁:
lockf()在大多数情况下仅作为fcntl()的接口实现
fcntl()锁绑定到进程,而不是文件描述符如果一个进程有多个针对特定文件的打开文件描述符,则用于获取锁定的这些文件描述符中的任何一个都将重置锁定
-
BSD锁:
flock()锁绑定到文件描述符,而不是进程。
此外
通过测试进行的良好分析:咨询文件锁定-我对POSIX和BSD锁定的看法
摘要摘录:
- fcntl和flock样式的锁是完全正交的。任何同时提供这两种功能的系统(Linux)都将独立处理通过它们中的每一个获得的锁
- 当进程退出或中止时,POSIX和BSD锁都会自动释放
- POSIX和BSD锁在执行调用中都会保留,除非进程设置了FD_CLOEXEC标志,强制关闭文件描述符,而不是由新进程继承