COBEGIN / COEND
COBEGIN/COEND is a compound statement that runs each of its inner BEGIN ... END blocks on a separate thread. The initial thread waits at COEND for every internal thread to finish — a built-in fork/join barrier.
Why this shape rather than free-form thread spawning?
It guarantees structured concurrency: threads created together finish together, so there’s no way to “leak” a thread past its enclosing block. The downside is expressiveness — the fork/join pattern makes it restricted to trees (lattices) of threads, not arbitrary thread graphs. Arbitrary graphs need WAIT.
uC++ form
#include <uCobegin.h>
int i;
void p1( ... ); void p2( ... ); void p3( ... );
COBEGIN // threads execute statements in block
BEGIN i = 1; END
BEGIN p1( 5 ); END // order and speed of internal
BEGIN p2( 7 ); END // thread execution is unknown
BEGIN p3( 9 ); END
COEND // initial thread waits for all internalsDynamic thread count via recursion
void loop( int N ) {
if ( N != 0 ) {
COBEGIN
BEGIN p1( ... ); END
BEGIN loop( N - 1 ); END // recursive call
COEND
}
}
cin >> N;
loop( N );Limitation — trees only
The thread graph implied by nested COBEGIN/COEND is strictly a tree. You can’t express “p starts before f, both finish before s4” without creating artificial nesting. For arbitrary graphs, use WAIT.