[cpp-threads] High-level concurrency issues
Boehm, Hans
hans.boehm at hp.com
Tue Oct 18 00:18:59 BST 2005
> >
> > I agree that typical developers must never need to know about the
> > memory model. (Makes me think of Jack Nicholson's character saying:
> > "The truth? You can't handle the truth.")
> >
> > But if you mean that 'doing the right locking' is the
> answer, I would
> > disagree with that because locks are known to be inherently
> > inappropriate for building modern software -- they aren't
> composable.
>
> FWIW, that's what rang the biggest alert bell to me, too.
>
Somewhat playing devil's advocate here, could someone make that
statement about "not composable" precise? I've certainly seen it
before, but I think it would help to understand exactly what we're
talking about here.
My general model of how when you acquire locks is:
1) Classes are designed to be thread-safe in the SGI STL sense: It is
the clients responsibility to ensure that a (logical) write access never
occurs concurrently with another access to the object. If two
concurrent (logical) read accesses to the object require a write behind
the scenes (e.g. to update a cache), then it is the objects
responsibility to provide locking for sufficient mutual exclusion behind
the scenes. Effectively objects I construct are thread-safe in the same
sense that primitive integers are thread-safe in pthreads.
2) If I write client code that may write to an object and make another
access to the same object, I must ensure that those accesses cannot take
place concurrently, e.g. by acquiring a lock around them.
3) If I need to ensure atomicity of a sequence of operations with
respect to some other operations, I presumably already need to acquire a
lock by rule (2), and I then need to avoid releasing the lock between
operations.
This can get me into trouble if atomicity or other considerations
require me to hold a lock during a client call-back, for example. But
in most cases, it seems to work tolerably well, and layers of calls seem
to compose reasonably. And I'm not 100% convinced that the cases in
which it breaks don't have single-threaded lock-free analogs in which I
break object invariants with an unintentional recursive call.
(Transactional memory might be better, but we're not ready to
standardize that, I think.)
This does not mesh at all well with a model in which all locking is done
on entry to member function, and locks the object itself. But I've
stated previously that I don't like that model. And I don't claim I
know how to program with it.
Hans
More information about the cpp-threads
mailing list