This commit is contained in:
hsutter
2015-12-21 16:21:33 -08:00
parent 6156e95782
commit 9c93ba6c5f

View File

@@ -9383,15 +9383,39 @@ See also:
It is hard to be certain that concurrency isn't used now or sometime in the future. It is hard to be certain that concurrency isn't used now or sometime in the future.
Code gets re-used. Code gets re-used.
Libraries using threads my be used from some other part of the program. Libraries using threads my be used from some other part of the program.
Note that this applies most urgently to library code and least urgently to stand-alone applications.
##### Example ##### Example
??? double cached_computation(double x)
{
static double cached_x = 0.0;
static double cached_result = COMPUTATION_OF_ZERO;
double result;
if (cached_x = x)
return cached_result;
result = computation(x);
cached_x = x;
cached_result = result;
return result;
}
Although `cached_computation` works perfectly in a single-threaded environment, in a multi-threaded environment the two `static` variables result in data races and thus undefined behavior.
There are several ways that this example could be made safe for a multi-threaded environment:
* Delegate concurrency concerns upwards to the caller.
* Mark the `static` variables as `thread_local` (which might make caching less effective).
* Implement concurrency control, for example, protecting the two `static` variables with a `static` lock (which might reduce performance).
* Have the caller provide the memory to be used for the cache, thereby delegating both memory allocation and concurrency concerns upwards to the caller.
* Refuse to build and/or run in a multi-threaded environment.
* Provide two implementations, one which is used in single-threaded environments and another which is used in multi-threaded environments.
**Exception**: There are examples where code will never be run in a multi-threaded environment. **Exception**: There are examples where code will never be run in a multi-threaded environment.
However, there are also many examples where code that was "known" to never run in a multi-threaded program However, there are also many examples where code that was "known" to never run in a multi-threaded program
was run as part of a multi-threaded program. Often years later. was run as part of a multi-threaded program. Often years later.
Typically, such programs lead to a painful effort to remove data races. Typically, such programs lead to a painful effort to remove data races.
Therefore, code that is never intended to run in a multi-threaded environment should be clearly labeled as such.
### <a name="Rconc-races"></a> CP.2: Avoid data races ### <a name="Rconc-races"></a> CP.2: Avoid data races