spawn s;creates a new thread to execute the statement s, which can be an arbitrary statement, including a compound one. All local variables in scope at the spawn statement become read-only constants in the spawned thread. This prevents unsynchronized access to them by the spawning and spawned threads.
The spawned and spawning threads are guaranteed to run concurrently. This contrasts with conc, which is an annotation This guarantee provides the programmer with more direct control over concurrency but can be expensive to enforce, and should be used only when absolutely vital. In this context, ``concurrently'' means only that neither must wait for the other. The execution of spawner and spawnee will be interleaved if that is required. This is formally known as weak fairness.
void main(void) {
Worker worker;
int total = compute_total(worker);
}
int compute_total(Worker &worker) {
reply(worker.total());
worker.clear_caches();
}
In the above example, compute_total is ready to return an answer before it has finished executing; using the reply idiom allows compute_total and main to continue concurrently.
int factorial(int i) {
if (i < 1)
return 1;
else
spawn reply(i*factorial(i-1));
}
The expression e will be spawned and the spawned thread will return he result to the caller of the spawning function. The reply object can also be passed out of a function, effectively delegating the job of returning a value to some other function. This can be used to create synchronization structures, such as the barrier shown below.
class Barrier {
int limit;
int count;
reply_t replies[];
public:
Barrier(int ilimit) {
count = 0;
limit = ilimit;
replies = new reply_t[ilimit];
}
void wait(void) {
replies[count++] = reply;
if (count == limit)
for(int i = 0; i < limit; i++)
replies[i]();
}
};
With the Barrier given above, functions can synchronize by all calling wait, where the reply objects are stored into an array. When they have all arrived, the barrier will return values to all of them simultaneously.
Barrier b(10);
void Worker::work(void) {
// computation here
b.wait();
// communication here
b.wait();
};