Skip to content

🌐 閱讀中文版

A Pitfall of Linux fcntl File Locks: They Don't Work Across Threads in the Same Process ​

TIP

Collected into a note (in Chinese): fcntl File Lock

On Linux, fcntl provides read/write file locks that work across processes. There is one small pitfall, though: within a single process, you cannot use these locks across threads.

Two threads in process B share one read lock while process A updates with a write lock

For example, say process A periodically updates the directory /srv/mydata, and takes a write lock on /srv/mydata.lock while updating. Meanwhile, thread 1 of process B needs to read /srv/mydata/data1, so it takes a read lock on /srv/mydata.lock.

But if process B also has a thread 2 that reads /srv/mydata/data2, thread 2 cannot also read-lock /srv/mydata.lock. fcntl locks are per process: if threads 1 and 2 both take the read lock, then as soon as one of them unlocks, the whole process no longer owns the lock.

In other words, if any thread closes any file descriptor for that file, all of the process's locks on it are released, no matter which file descriptor was used to obtain them. So when using fcntl file locks, pay close attention to how processes and threads relate, or you may get unexpected races.

One possible fix is to split it into two locks:

Split into lock 1 and lock 2, with each thread holding its own read lock

References ​

If a process closes any file descriptor referring to a file, then all of the process's locks on that file are released, regardless of the file descriptor(s) on which the locks were obtained.

Just observe 👀