We noted in Section 1.3.1 that determinism can greatly simplify program development. CC++ does not provide any guarantees of deterministic execution: indeed, the basic execution model is highly nondeterministic, allowing as it does the interleaved execution of multiple threads in a single address space. Nevertheless, there are simple rules that, if followed, allow us to avoid unwanted deterministic interactions. In particular, a CC++ program is easily shown to be deterministic if it uses a task-based concurrency model (one thread per processor object) and if tasks interact only by using the channel library used in Program 5.3, with one sender and one receiver per channel.
While a task/channel model ensures determinism, there are also circumstances in which it is advantageous to use CC++ constructs in more flexible ways. For example:
par { value = pobj->get_remote_value(); perform_computation(); } use_remote_value(value);
These more general forms of concurrency and communication introduce the possibility of complex, nondeterministic interactions between concurrently executing threads. However, the risk of nondeterministic interactions can be reduced substantially by avoiding the use of global variables, by making shared data structures have the sync attribute, and by ensuring that accesses to nonsync shared data structures occur within atomic functions.
© Copyright 1995 by Ian Foster