如果lockf
与0偏移量一起使用,那么在独占模式下使用时flock
和lockf
之间的差异是什么?
我问,因为我正在阅读基于平台有条件地编译这两个函数中的任何一个的代码,并且我想了解可能的原因。
答案 0 :(得分:36)
flock()
和lockf()
之间的实际区别在于语义(关闭和传递的行为),对NFS和其他共享文件系统的适用性,以及咨询锁是否对其他进程可见是否使用fcntl()
锁定。
您正在使用的库只具有基于当前平台选择所需语义的逻辑。
如果语义(描述符传递,分叉等行为)可以接受,你应该更喜欢lockf()
/ fcntl()
锁定Linux中的flock()
锁,因为前者有效在NFS等文件系统上,而后者则没有。 (在BSD和Mac OS X上,我认为您需要明确使用fcntl()
。)
在Linux中,lockf()
只是fcntl()
的包装,而flock()
锁是独立的(并且只能在本地文件系统上工作,而不是在2.6之前的内核上安装NFS) 0.12)。也就是说,一个进程可以对文件具有建议的独占flock()
锁定,而另一个进程对该文件具有建议的独占fcntl()
锁定。两者都是咨询锁,但它们不相互作用。
在Mac OS X和FreeBSD上,lockf()
/ flock()
/ fcntl()
锁定所有交互,但建议开发人员只使用其中一个接口应用。但是,只有fcntl()
锁定才能在NFS mounts上工作(显然,只有当NFS客户端和服务器都配置为支持记录锁定时,这在例如Web托管环境中是罕见的;这是一个巨大的原因。一些网络(框架)开发人员的头痛。)
POSIX没有明确指定lockf()
/ flock()
/ fcntl()
锁应该如何交互,并且过去存在差异。现在,情况已经平静下来了,人们可以大约说出
fcntl()
锁是最可靠的
在整个架构中,他们最有可能正确地工作,例如共享文件系统 - 例如NFS和CIFS安装。
大多数时候,lockf()
被实现为"简写" fcntl()
另一种选择,"简写"对flock()
来说,是可能的,但现在很少见。
fcntl()
和flock()
具有不同的语义。继承和自动发布
fcntl()
个锁在exec()
内保留,但不会在fork()
内继承。当拥有进程关闭引用同一文件的任何描述符时,将释放锁。
在Linux,FreeBSD和MAc OS X中,flock()
锁与开放文件描述符耦合:传递描述符也会传递锁。 (手册页指出&#34;锁在文件上,而不在文件描述符&#34; 。这不是矛盾。它只是意味着锁适用< / em>到文件。它仍然耦合到描述符,这样复制描述符也会传递相同的锁。)因此,多个进程可能具有相同的独占通知flock()
如果他们在flock()
呼叫后从发起人处获得描述符,则同时锁定同一文件。
文件锁定是一个非常复杂的问题。只需坚持fcntl()
锁定,我个人就获得了最好的结果。语义学。 fcntl()
锁是最容易使用的,在某些情况下可能是坦率的真气;只是我发现它能够产生最好 - 最可靠,最便携,最不令人惊讶的结果。
答案 1 :(得分:1)
条件编译的最可能原因是这两个函数都不适用于每个平台。