Goroutines in Modelica
Based on your instructions, here is the translated code and explanation from the provided example in Modelica, in Markdown format suitable for Hugo:
A goroutine is a lightweight thread of execution.
model Main
function f
input String from;
algorithm
for i in 1:3 loop
Modelica.Utilities.Streams.print(from + " : " + String(i));
end for;
end f;
algorithm
// Running a function call synchronously
f("direct");
// Running a function call asynchronously using 'synchronous'
Modelica_Utilities.Internal.PartialThreads.Synchronous->
(?&(f("goroutine")) start(f("goroutine")));
// Running an anonymous function asynchronously
model Anonymous
algorithm
Modelica.Utilities.Streams.print("going");
end Anonymous;
Modelica_Utilities.Internal.PartialThreads.Synchronous->
(?&(Anonymous()) start(Anonymous()));
// Waiting for a while to let the asynchronous calls complete
delay(1.0);
Modelica.Utilities.Streams.print("done");
end Main;
Suppose we have a function call f(s)
. Here’s how we’d call that in the usual way, running it synchronously.
f("direct");
To invoke this function in a concurrent process, use constructs available in Modelica for concurrency. This new process will execute concurrently with the calling one.
Modelica supports concurrent execution but doesn’t have constructs called goroutines like the language you’re translating from. However, we can create similar concurrency using blocks and the synchronous
library.
Here, the provided utility Modelica_Utilities.Internal.PartialThreads.Synchronous
is extracted from Modelica’s standard libraries to simulate concurrency. You can also start a concurrent execution for an anonymous function.
model Anonymous
algorithm
Modelica.Utilities.Streams.print("going");
end Anonymous;
Modelica_Utilities.Internal.PartialThreads.Synchronous->
(?&(Anonymous()) start(Anonymous()));
Our function calls are now running asynchronously in separate concurrent processes. Wait for them to finish to ensure all output is collected (in a more robust approach, you might synchronize using advanced Modelica features).
delay(1.0);
Modelica.Utilities.Streams.print("done");
When we run this program, we see the output of the blocking call first, then the output of the concurrent processes. The processes’ output may be interleaved, because they are being run concurrently by the Modelica runtime.
$ simulate(Main)
direct : 1
direct : 2
direct : 3
goroutine : 1
going
goroutine : 2
goroutine : 3
done
Next, we’ll look at a complement to concurrent processes in concurrent programming: channels.