|
Boost : |
From: Beman Dawes (bdawes_at_[hidden])
Date: 2001-05-23 12:21:29
At 09:38 AM 5/23/2001, williamkempf_at_[hidden] wrote:
>> it. There is nothing wrong with a mutex.
>
>No, but there is something wrong with a mutex being used at this
>granularity.
>
>> Think about needs for counters of various totals to be reported by
>several
>> worker threads. Each thread would keep its own local totals (so
>they could
>> be updated efficiently without locking), but then just before
>closing down
>> would update the shared thread_safe_int_least32_t program totals.
>No
>> particular efficiency issue there, just safety.
>
>That's simple addition, not a full range of integral operations, so
>it's not much of an example of the need for a full
>thread_safe_int_least32_t. This particular example would best be
>served by "traditional" synchronization, i.e. you'd roll the
>synchronization yourself. Why? Well, it's just to simple of an
>example to be worth addressing in a library.
It may be simple, but who wants to write even a simple class every time
such a common need arises? And test it, and document it, and so on. I'd
rather have it (and other common usage patterns) as part of a library.
> For instance, it's
>quite possible that there will be multiple such totals that need to
>be updated and it would be better to use a single mutex for all of
>them then to use a mutex per total as would be done by a library
>solution.
But that is more error prone (if the mutex is manipulated manually, rather
than wrapped in a class), is slower (if there are multiple threads
contending for otherwise unrelated counters), and in general making an
assumption about what a programmer wants to optimize. Maybe the programmer
wants to favor programming effort, safety, and speed rather than mutex
memory space.
>> Now of course there could be an application mutex, but why bother?
>It just
>> opens up the possibility of misuse. A thread_safe_int_least32_t
>would wrap
>> the functionality up in a nice safe package that would be very hard
>to
>> misuse. That's what C++ classes are all about.
>
>The reason to bother is to attain the optimal granularity of lock
>(and an "application mutex" might not fit that bill either). A
>threading library can't predict what level of granularity is optimal
>since it's going to depend on the application, so such a type just
>isn't appropriate.
>
>Beyond that, there's a severe problem with a
>thread_safe_int_least32_t that behaves as an int. The level of
>granularity of such a lock can actually lead to errors in usage. For
>example:
>
>thread_safe_int_least32_t i = 10;
>i = (i + 2) / 2;
>
>The above expression should be executed "atomically" (as in no other
>thread can change the value of 'i' while the expression is being
>evaluated) but it is not. The internal mutex is only locked during
>the call to a single operation, so it's possible for another thread
>to interrupt and change the value of 'i' in between the '+' and
>the '/'. It can even interrupt before the assignment! This is why
>atomic_t has very specific functions that can be called such as inc()
>and dec() and doesn't have overloaded operators such as '++' and '--'.
So reduce it to functions which can be safely provided.
The point is to give programmers a nice palette of mid and hi level tools,
not just the very low level ones. Jens Maurer's bounded queue was a good
example.
--Beman
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk