Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a writer-preferring read/write lock for *nix processes

There is a Unix function called flock() that processes can use to obtain either shared ("read") access or exclusive ("write") access to a resource. The problem is that it starves those processes that are requesting exclusive access. Such a request remains queued until such time that there are no processes holding a shared lock; meanwhile, new requests for a shared lock are granted them "ahead of" the process that is waiting for an exclusive lock.

Clearly, the more processes there are requesting shared locks, the longer a writer will have to wait for that fortuitous window of time in which there are no outstanding shared locks being held.

The behavior I seek is this: once a writer has requested an exclusive lock, subsequent readers who request a shared lock will be queued behind the writer. The name for this type of lock, I'm told, is "writer-preferring read/write lock".

There are several posts (this one in particular) that address this question, but at the thread level. What I need is a Unix/Linux-oriented solution for coordinating processes in this manner.

UPDATE: I need for the solution to handle the possibility that a participating process may crash while it holds a lock, by automatically removing the lock.

like image 256
Chap Avatar asked Dec 23 '14 17:12

Chap


1 Answers

You can use the method described in the referenced question for inter-process as well as inter-thread synchronization. You have to make sure the pthread_rwlock_t object is in memory shared between the processes you want to synchronize, and use the pthread_rwlockattr_setpshared() function to mark the pthread_rwlockattr_t object you use to initialize the pthread_rwlock_t as PTHREAD_PROCESS_SHARED.

If you need your synchronization to reset itself when the process exits, you'll need to use a reader-writer lock based on a different synchronization primitive. I think System V semaphores (otherwise known as XIS IPC semaphores) should do the trick, since they are supposed to reset themselves when a process that has manipulated them exits without resetting them. System V semaphores are an optional feature of the Linux kernel.

You might want to use a library that has higher level locking abstractions for this-- if you are using C++, you can use boost synchronization. However, I'm not sure that boost synchronization supports locks backed by System V IPC semaphores-- you might be forced to roll your own reader-writer lock on top of a Sys V semaphore set. Specifically, you'll need a read semaphore, a write semaphore and a write queue semaphore. Writers increment the write queue and wait for the read and the write semaphore to go to 0, then increment the write semaphore. Readers wait for the write queue and write semaphore to go to 0, then increment the read semaphore.

like image 134
antlersoft Avatar answered Sep 23 '22 12:09

antlersoft