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

时间:2015-04-13 17:25:43

标签: c locking posix

我正在阅读几个小时,但无法理解两个锁之间的差异是什么。我唯一理解的是fcntl()锁提供了一个可以锁定特定字节的粒度锁,只有fcntl()支持NFS锁定。

据说差异在于它们的语义,它们在被dup()fork()复制时的行为方式,但我无法理解实践中有什么不同。

我的情况是我正在写入基于fork()的服务器中的日志文件,其中每个分叉进程在发生某事时写入同一文件。为什么我要使用flock(),为什么我要使用fcntl()锁?

1 个答案:

答案 0 :(得分:10)

我试图根据可用的文档找出差异并得出以下结论(如果我错了请纠正我):

使用fcntl()(POSIX):

  • 您在文件系统级别创建锁定记录,包括进程ID。

  • 如果进程终止或关闭此文件的任何文件描述符,系统将删除锁定记录。

  • 如果没有使用写访问权限打开文件描述符,则对独占锁的请求将失败。

  • 简单地说:fnctl锁定用作进程< - >文件关系,忽略文件描述符

flock()(BSD)是不同的(Linux:因为内核2.0,flock()本身就是作为系统调用实现的,而不是作为对fcntl的调用在GNU C库中模拟的):

  • flock()在系统的“打开文件描述”上创建锁。 “打开文件描述”由open()调用生成。

  • 文件描述符(FD)是对“打开文件描述”的引用。由 dup() fork()生成的FD引用相同的“打开文件描述”。

  • 一个进程可以通过多次打开()文件为一个文件生成多个“打开文件描述”

  • flock()通过FD在“打开文件描述”上放置锁定

  • 因此flock()可用于在进程和线程之间同步文件访问(在一个或多个进程中)。

  • 有关“打开文件说明”的详细信息,请参阅flock(2),尤其是open(2)手册页。

在您的场景中,您可能希望使用基于fcntl()的锁,因为您的分叉进程将自己打开()日志文件,并且不希望继承带有可能放置锁的文件描述符。

如果您需要在多个线程之间进行同步(可能在多个进程中),则应使用基于flock()的锁,如果您的系统支持它们而不通过fcntl()进行仿真。然后每个线程都需要打开()文件,而不是使用dup()ed或fork()ed句柄。