Boost logo

Boost :

From: flameframe_at_[hidden]
Date: 2001-08-13 06:38:30


--- In boost_at_y..., "Alexander Terekhov" <terekhov_at_d...> wrote:
>
> > > > I have written some high level abstractions
> > > > like reader-writer lock using events without getting something
> > like
> > > > CVs in source code.
> > >
> > > could you please show your reader-writer lock using events ?
> > >
> > > regards,
> > > alexander.
> >
> >
> > Just a cut-edit-and-paste from simple redaction of a class:
> >
> > // Comments :
> > // class Mutex - wraps Win32 mutex API
> > // class Event - wraps Win32 event API
> > // class Enter - wraps
WaitForSingleObjectEx/WaitForMultipleObjectsEx
> > API
> > //Usage:
> > //class A : RWLock
> > //{
> > // void read_function() const
> > // {
> > // ReadEnter guard(this);
> > // ....
> > // }
> > // void write_function()
> > // {
> > // WriteEnter guard(this);
> > // ....
> > // }
> > //};
> > struct RWLock
> > {
> > class ReadEnter; class WriteEnter;
> > friend class ReadEnter; friend class WriteEnter;
> >
> > Mutex lock;
> > Event noReaders;
> >
> > int numOfReaders;
> >
> >
> > void oneReaderMore()
> > {
> > numOfReaders++;
> > noReaders = false; //Reset manual reset-event
> > }
> > void oneReaderLess()
> > {
> > if( --numOfReaders == 0 ) // ( no more readers )
> > {
> > noReaders = true; //Set manual reset-event
> > }
> > }
> > RWLock()
> > {
> > numOfReaders = 0 ;
> > noReaders = true ;
> > }
> >
> > class ReadEnter
> > {
> > RWLock* s;
> > DWORD timeout;
> > public:
> > explicit ReadEnter( RWLock*s_
> > , DWORD timeout_=INFINITE)
> > : s(s_),timeout(timeout_)
> > {
> > Enter e(s->lock,timeout);
> > s->oneReaderMore();
> > }
> > ~ReadEnter()
> > {
> > Enter e(s->lock,timeout);
> > s->oneReaderLess();
> > }
> > };
> > class WriteEnter : public Enter
> > {
> > public:
> > explicit WriteEnter( RWLock*s_
> > , DWORD timeout=INFINITE)
> > : Enter(s->lock, s->noReaders
> > , waitAll, timeout)
> > {
> > }
> > };
> > };
>
> thanks. note however, while using WaitForMultiple( mutex, event... )
> you have precluded various race conditions but you are paying rather
> high price for it:
>
> a) you have to synchronize quite expensive set/reset event calls
> (you do it with mutex locked making internal event synchronization
> just a useless/boring overhead for you);

Probably you are right. I am not sure how much work is performed in a
background of SetEvent call. With respect to example you mentioned:
 
- some lock in my code requires
   lock/unlock mutex + set event call
- in Programming with POSIX Threads
   lock/unlock mutex + CV management

I am by no means a threading expert but from the above I can not make
deduction that event's price is higher.

>
> b) with WaitForMultiple( mutex, event... ) you have introduced
> another monitor (it watches the states of multiple synch.
> objects) which means that you've got even more internal locking
> and redundant internal signaling/wakeups/checks/block-again and/or
> internal transfer of synch. objects (mutex) ownership across thread
> context switches..
>

Again, it depends on hidden implemetation details same way as in my
previous comment. If you are a Win32 guru I can believe to you that
you are right (staying with my own opinion although :). It would be
nice to see some time comparisions.

> Q) taking into account the issues above do you still think that
> your solution is better than (or just "equal to") some CV(s)
> based solution; e.g:
>
> http://www.aw.com/cseng/titles/0-201-63392-2/code/rwlock.c
>
> ?
>
> regards,
> alexander.

Who knows? I am far from saying that my solution (to do the justice-
actually there were a lot of people before me writing the same) is
*better* than anyone's else.

Anyway, I have mentioned event-based solutions just to object that it
always result either to race conditions or to CV-equivalent.

As long as performance is a matter of question I (personally) prefer
events in this special case because it (comparing to 'Programming
with POSIX Threads' example) needs less code and is easier to
understand.

Regards,
Vitalij.


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