|
Boost : |
From: William Kempf (sirwillard_at_[hidden])
Date: 2000-08-22 11:09:27
--- In boost_at_[hidden], Beman Dawes <beman_at_e...> wrote:
> William Kempf wrote:
>
> > ...
> >
> >> Another possibility, which I think Beman already suggested, is
to
> >> expose the mutex as a smart pointer class with an operator->
that
> >> handles the locking.
> >
> >This is a very old technique. It can be a useful one, but it
doesn't
> >solve all of the problems (mot notably it won't solve the problem
of
> >multiple calls on an object needing to occur synchronously).
>
> Could you explain that in a bit more detail? Sorry to be dense.
Do you
> mean there are some use patterns that require two (or more) member
> functions be called as a unit? Is that a design problem with the
class
> being wrapped?
It's not necessarily a design problem. Think about std::vector.
There's no way to make use of std::vector thread safe by using an
internal monitor/mutex/whatever. Something as simple as:
v.erase(v.begin());
is thread unsafe. Using the lock_pointer idiom you have:
pv->erase(pf->begin());
which is still not thread safe. The granularity of the lock is too
low. We need a lock around the transaction (multiple method call) to
insure thread safety here.
Not all classes can be designed with full proof internal thread
synchronization (in fact, I'd dare say that most can't). The
lock_pointer approach is just an inversion of internal
synchronization. For this reason, it falls down in the same cases
where internal synchronization falls down.
Note that I'm not saying that neither internal synchronization nor
the lock_pointer aren't valid idioms. All that I'm saying is that
they aren't a silver bullet, especially in the multi-paradigm world
of C++. They may be prefered techniques, but they can't be the only
techniques.
> >Further, it requires some discipline from the programmer.
>
> I'm missing that too. The point of the wrapper was that the
programmer
> wouldn't have to apply a discipline.
The discipline is in using the lock_pointer appropriately. No smart
pointer is with out the need for discipline in using them correctly.
In the case of lock_pointer it mostly amounts to requiring the
programmer to insure that a raw pointer to the object may not be
attained (or at the very least, that a raw pointer isn't used). The
lock_pointer makes it easier to serialize access to an object that
wasn't designed for MT, but for safety internal synchronization is
probably still better.
Bill Kempf
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk