Boost logo

Boost :

From: Anthony Williams (anthony.williamsNOSPAM_at_[hidden])
Date: 2003-10-20 09:02:42


Daniel Spangenberg <dsp_at_[hidden]> writes:
> Question is: Can I use the current thread library to realize a
> read/write mutex (accepting
> multiple readers from different threads but prevents writer from access)
> on my own?
> If so, how should I do this? If this would help to give a more precise
> answer: My
> target platform is Win32, although a generic solution would be
> wunderful, of course ;-))
> (More worse: It must be a mutex accessible/protectable from threads of
> different
> processes...).

I have an implementation of a read/write mutex for win32, which uses a critical
section and a semaphore along with a writer flag and a reader count (and another
critical section so the test harness can get at the reader/writer info). It may
not be the most efficient implementation, but I am fairly sure that it works
correctly.

I use native Win32 facilities, but I expect the code could be changed to
boost::thread facilities very easily. Also, on systems which support such a
concept natively, I would hope that my code could be converted into a wrapper
for the native support.

Making it work across processes would be tricky --- you would have to use a
named mutex and named semaphore, and that requires generating names known to
both the processes involved, but which don't clash with the names of any other
mutexes or semaphores in the system.

> My assumption is, that I could use *one* single mutex for both read and
> write access
> and probably a kind of reader counter (similar to recursive_mutex), is
> that right?

The logic I use is this:

Initially, the writing flag is clear, the reader count is zero, the critical
section is unlocked and the semaphore is signalled.

To acquire a write lock, the code locks the CS and checks the reader count. If
the reader count is non zero, unlock the CS and wait for the semaphore to be
signalled, then repeat until the reader count is zero. Leave the CS locked and
set the writer flag.

To release the write lock, signal the semaphore, clear the write flag and unlock
the CS.

To acquire a read lock, lock the CS and increment the reader count. Clear the
semaphore.

To release a read lock, lock the CS, decrement the reader count and signal the
semaphore if the reader count is now zero.

Note that a write lock holds the CS for the duration, since there can only be
one write lock. This causes all read requests to queue. OTOH, the read lock only
holds the CS whilst it does the lock/unlock operation, since there is no clear
owner of the CS with the multiple readers, as the first to acquire will not
necessarily be the last to release.

I can post the code if you wish. Maybe it could be added to Boost.Threads

Anthony

-- 
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk