Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between locking with `fcntl` and `flock`?

Tags:

c

posix

locking

I'm reading for hours but can't understand what is the difference between the two locks. The only thing I understand is that fcntl() lock is offering a granular lock that can lock specific bytes and that only fcntl() supports NFS locking.

It's said that the difference is in their semantics, how do they behave when being duplicated by dup() or while fork(), but I can't understand what is the difference in practice.

My scenario is that I'm writing to a log file in a fork() based server, where every forked process is writing to the same file when something happens. Why would I want to use flock() and why would I want to use fcntl() locks?

like image 899
Quaker Avatar asked Apr 13 '15 17:04

Quaker


1 Answers

I have tried to figure out the differences based on available documentation and took the following conclusions (please correct me if I am wrong):

With fcntl() (POSIX):

  • you create a lock record on the file at filesystem level including process id.

  • If the process dies or closes any filedescriptor to this file, the lock record gets removed by the system.

  • A request for an exclusive lock shall fail if the file descriptor was not opened with write access.

  • simply: fnctl locks work as a Process <--> File relationship, ignoring filedescriptors

flock() (BSD) is different (Linux: since kernel 2.0, flock() is implemented as a system call in its own right rather than being emulated in the GNU C library as a call to fcntl):

  • flock() creates locks on systems's "Open file descriptions". "Open file descriptions" are generated by open() calls.

  • a filedescriptor (FD) is a reference to a "Open file description". FDs generated by dup() or fork() refer to the same "Open file description".

  • a process may generate multiple "Open file descriptions" for one file by opening() the file multiple times

  • flock() places it's locks via a FD on a "Open file description"

  • therefore flock() may be used to synchronize file access among processes as well as threads (in one ore more processes).

  • see flock(2) and especially open(2) man pages for details on "Open file descriptions".

In Your scenario you probably want to use fcntl() based locks, because your forked processes will open() the logfile on their own and do not expect to inherit a filedescriptor with a possibly placed lock.

If you need synchronisation among multiple threads, possibly in more than one process, you should use flock() based locks if your system supports them without emulation by fcntl(). Then every thread needs to open() the file rather than using dup()ed or fork()ed handles.

like image 101
NorbertM Avatar answered Nov 10 '22 01:11

NorbertM