I have some questions regarding read-write locks in POSIX Pthreads on a *nix system, say Linux for example.
I wish to know what is the default bias for read write lock i.e does it prefer reads over writes or vice versa ? Does it provide some api to change this default behaviour.
Does posix pthread provide some api so that we could change the pthread_rwlock_t to prevent writer starvation ? From what i have read(please correct me if i am wrong), the default implementation is biased towards reader threads and so writer threads can face starvation.
I have read the sample implementation of rw lock from the book Programming with Posix threads by David Butenhof.
I wish to know how posix pthreads handle starvation of writer threads ? Is there some api using which we could set the attributes of the read write lock that would prevent write starvation (i have never heard about that) ? Or does the user have to handle this problem ?
If you think that the answer is implementation-defined then please give me example of how it's done in Linux, because thats what i am looking for.
Please note that i just want solutions for a *nix system. Don't think that i am rude, but posting some windows-specific code is useless for me.
Thank you all for your help and patience :)
Write-preferring RW locks avoid the problem of writer starvation by preventing any new readers from acquiring the lock if there is a writer queued and waiting for the lock; the writer will acquire the lock as soon as all readers which were already holding the lock have completed.
In many situations, data is read more often than it is modified or written. In these cases, you can allow threads to read concurrently while holding the lock and allow only one thread to hold the lock when data is modified. A multiple-reader single-writer lock (or read/write lock) does this.
Instead of having a single lock method, they have two - one for readers and one for writers. When readers enter the critical section they invoke the reader lock (and then reader unlock on exit); when writers enter the critical section they invoke the writer lock (and then writer unlock on exit).
Acquiring a read lock ensures that a different transaction does not modify or delete a row while it is being read. Any number of transactions can acquire read locks on any row at the same time, so read locks are sometimes referred to as shared locks, or non-exclusive locks.
This does indeed depend on the implementation - so since you have asked about Linux specifically, my comments are refer to the current NPTL implementation of pthreads, which is used in modern glibc.
There are two related, but separate, issues here. Firstly, there is this situation:
The default action here is to allow the reader to proceed - effectively "jumping the queue" over the writer. You can, however, override this. If you use the pthread_rwlockattr_setkind_np()
function to set the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
flag on the attr
that you pass to pthread_rwlock_init()
, then your rwlock will block the reader in the above situation.
The second situation is:
In this situation, NPTL will always wake up a writer in preference to a reader.
Taken together, the above means that if you use the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
flag, your writers shouldn't be starved (of course, now a continuous stream of writers can starve the readers. C'est la vie). You can confirm all this by checking the sources (it's all very readable1) in pthread_rwlock_rdlock.c and pthread_rwlock_unlock.c.
Note that there is also a PTHREAD_RWLOCK_PREFER_WRITER_NP
, but it appears not to have the right effect - quite possibly a bug (or possibly not - see comment by jilles below).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With