用'fcntl'和'flock'锁定有什么区别?

lnvxswe2  于 2022-12-02  发布在  其他
关注(0)|答案(1)|浏览(119)

我阅读了几个小时,但无法理解这两个锁之间的区别。我唯一理解的是fcntl()锁提供了一个可以锁定特定字节的粒度锁,只有fcntl()支持NFS锁定。
据说区别在于它们的语义,当它们被dup()或while fork()复制时,它们会如何表现,但我不明白在实践中有什么区别。
我的场景是我在基于fork()的服务器上写日志文件,当 * 某事 * 发生时,每个分叉进程都在写同一个文件。为什么我要使用flock()?为什么我要使用fcntl()锁?

gcuhipw9

gcuhipw91#

我试图根据现有的文件找出差异,并得出以下结论(如果我错了,请纠正我):
使用fcntl()(POSIX):

  • 您在文件系统级别创建了一个包含进程ID的文件锁记录。
  • 如果进程终止或关闭此文件的任何文件描述符,则系统将删除锁定记录。
  • 如果文件描述符未使用写访问打开,则独占锁请求将失败。
  • 简单:fnctl锁作为Process <-->File关系工作,忽略文件描述符

flock()(BSD)不同(Linux:从内核2.0开始,flock()被实现为一个系统调用,而不是在GNU C库中被模拟为对fcntl的调用):

  • flock()在系统的“打开文件描述”上创建锁。“打开文件描述”由open()调用生成。
  • 文件描述符(FD)是对“打开文件描述”的引用。由**dup()fork()**生成的FD引用相同的“打开文件描述”。
  • 进程可以通过多次open()文件来为一个文件生成多个“打开文件描述
    *flock()通过“打开文件描述”上的FD放置其锁
  • 因此flock()可用于在进程以及线程(在一个或多个进程中)之间同步文件访问。
  • 有关“打开文件描述”的详细信息,请参见flock(2),尤其是open(2)手册页。

在您的场景中,您可能希望使用基于fcntl()的锁,因为您的派生进程将自己打开()日志文件,并且不期望继承带有可能放置的锁的filedescriptor。
如果你需要在多个线程之间进行同步,可能是在多个进程中,你应该使用基于flock()的锁,如果你的系统支持它们,而不需要通过fcntl()进行仿真。然后每个线程都需要open()文件,而不是使用dup()ed或fork()ed句柄。
编辑2022:一个优秀的书面和额外的想法在这里:https://lwn.net/Articles/586904/

相关问题