The first example, Program Listing 3-9, uses channels for simple synchronization (refer to the example Program Listing 3-8 on page 3-32).
implement Command;
include "sys.m";
include "draw.m";
sys: Sys;
print: import sys;
sc: chan of int;
rc: chan of int;
Command: module {
init: fn(ctxt: ref Draw->Context, argv: list of string);
};
init(ctxt: ref Draw->Context, argv: list of string) {
sys = load Sys Sys->PATH;
sc = chan of int;
rc = chan of int;
for (i:=1; i<=5; i++) {
spawn func();
print("%2d\n", i);
sc<- = i;
<-rc;
}
}
func() {
i := <-sc;
print(" %2d\n", i);
rc<- = i;
}
The
init
thread initializes two channels that transport an integer. It then spawns a new thread with the function func
. The new thread begins execution in func
, where it blocks on the channel sc
until a message arrives (Line 29). Meanwhile, the init
thread continues to execute, printing the integer (Line 22) and sending the integer as a message on channel sc
, before it blocks on the channel rc
waiting for a return message (Line 24).
When func
receives the message on channel sc
, it continues to execute, printing the integer (Line 30) and sending the integer as a message on the channel rc
, before it terminates.
When init
receives the message on channel rc
(it has blocked waiting for it on Line 24) it starts the next iteration of the for
loop (Line 20) and the sequence starts over.