Goroutines in Pascal
Our example demonstrates the concept of lightweight threads of execution called goroutines. Here’s the original source code:
package main
import (
"fmt"
"time"
)
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}
func main() {
f("direct")
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
}("going")
time.Sleep(time.Second)
fmt.Println("done")
}
Let’s convert this example to Pascal, a language with a similar concept for concurrent execution using threads:
program GoroutinesExample;
uses
crt, sysutils;
procedure f(from: string);
var
i: integer;
begin
for i := 0 to 2 do
begin
writeln(from, ' : ', i);
sleep(100); // Add a slight delay to mimic concurrent behavior
end;
end;
begin
// Direct call
f('direct');
// Goroutine in Pascal: use a thread
begin
// Create a new thread
TThread.CreateAnonymousThread(
procedure
begin
f('goroutine');
end
).Start;
end;
// Anonymous function
begin
// Create another thread for the anonymous function
TThread.CreateAnonymousThread(
procedure
begin
writeln('going');
end
).Start;
end;
// Wait for the threads to complete
sleep(1000);
writeln('done');
end.
To run the program, save the code in a file named GoroutinesExample.pas
and use a Pascal compiler like Free Pascal to compile and run it.
$ fpc GoroutinesExample.pas
$ ./GoroutinesExample
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done
When we run this Pascal program, we see the output of the blocking call first, then the output of the two threads. The thread outputs may be interleaved, as threads are running concurrently.
Next, we’ll look at a complement to goroutines in concurrent programs: channels (though not natively available in Pascal, equivalent synchronization techniques can be explored).