Previous: Nesting Up: Structured Parallel Blocks: par Next: Examples
Pitfalls
In this section we describe several common errors to be
careful to avoid.
- The interleaving of actions composed in parallel is
arbitrary. The language makes no guarantees about how
often, or even how soon, instructions from a particular
thread will be executed. For example:
par {
while (1) g();
f();
}
The first statement in this case is an infinite loop. Instructions
from this loop could be executed for a very, very long time before
a single instruction from the second thread is chosen for
execution. Thus, we cannot expect to observe function f() even
begin execution.
- Declarations are not permitted at the level of scope of
a parallel block. This is consistent with the rules of variable
sharing for parallel blocks. For example:
par {
int x; //ERROR
x = 2;
}
Within nested levels of scope, however, declarations are permitted:
par {
{
int s;
s = f();
g(s);
}
for (int i=0; i<3; i++)
k(i);
}
- Gotos into, out of, or between statements at the level
of scope of a parallel block are not permitted. In particular, no
break, continue, goto,
or return statements are permitted.
In addition, the current implementation of the language places
the following restrictions on CC++ programs.
- No exceptions can be thrown inside parallel blocks.
- A file or stream on which I/O is performed should
be seen as a mutable variable. Thus, composing
I/O operations on the same file
in parallel is dangerous and should be avoided.
We will see a mechanism in Chapter
that permits
safe parallel composition of such operations. I/O operations
on different files or streams can safely be composed in parallel
with each other.