Reputation: 359
For a project I am thinking about using pthread reader-writer locks
or fcntl()-based file locks
. I have to choose on of them. Could you please explain the differences between them? What are the advantages and disadvantages?
Upvotes: 1
Views: 409
Reputation: 2360
They're two completely different tools and are generally used for different tasks. A fair or complete contrast between the two is difficult as it's like comparing apples to couches.
TL;DR:
fcntl(2)
:
pthread_rwlock
:
fcntl(2)
-based locks implement POSIX advisory locks on files, or ranges of bytes within the files. As they are advisory, nothing enforces these locks -- all processes (or threads) must cooperate and respect the semantics of the locks for them to be effective. For example, consider two processes A
and B
operating on some file f
. If process A
sets locks on f
, B
can completely ignore these locks and do whatever it likes. In general, this interface is used to protect access to entire files (or ranges within a file) between multiple threads and / or processes.
The pthread_rwlock
interface could also be considered an advisory locking system (all threads must use the API for the locking to be effective). However, it is not implemented on top of files and is not limited in scope to protecting access to files. A reader-writer lock is a form of shared memory mutual exclusion interface such that multiple readers may concurrently execute a critical section while writers are blocked, or such that individual writers may execute a critical section, blocking all other concurrent readers and writers. In general, this interface is used to safeguard access to shared mutable state (possibly shared memory, possibly file access) between multiple threads in a process in read-mostly workloads. This API is not typically used to protect concurrent access in multiple processes.
If I were faced with the decision on picking one of these interfaces for serializing access to some data, I'd expect to ask myself at least a couple of questions:
If the intent is largely to protect access to a file, but only ever in a single process, I might settle for using pthread_rwlock
. The downside to this approach is that if I ever needed to use multiple processes to access the file in the future, I wouldn't have a good way to express my locking intent to those other processes. Similarly, if I'm primarily trying to serialize access to some shared memory, I would use pthread_rwlock
because the fcntl(2)
interface expresses some intent on a file.
When trying to cooperate between multiple processes reading and writing a single file, I might use fcntl(2)
. However, this is likely to become very complicated, very quickly. For example, how do I handle events like truncation? Consider a case where process A
has read 1024 bytes into a file that is then truncated to 0 bytes by process B
. A
must then seek to the beginning of the file and wait for new data to be written to continue reading without errors -- or to correctly append new data itself!
Solving these issues requires more locked communication in additional files, and the complexity can quickly spiral out of control. If I was required to implement some sort of concurrent system working on a file, I'd likely choose multiple threads and use the pthread_rwlock
API. It's just easier to manage the totality of updates required to implement such a system in a single process. Without knowing the requirements you're faced with, it's rather difficult to guide one way or another.
Upvotes: 2