Goroutines in Scilab

Our example demonstrates the use of goroutines, a lightweight thread of execution. Here’s the full source code in Scilab.

function f(from)
    for i = 0:2
        disp(msprintf("%s : %d", from, i));
    end
endfunction

// Main function
function main()
    // Synchronous call
    f("direct");
    
    // Asynchronous calls using tasks
    tasks = [];
    task = function() f("goroutine"); endfunction;
    tasks = [tasks, task];
    task = function() disp("going"); endfunction;
    tasks = [tasks, task];
    
    // Start asynchronous tasks
    for task = tasks
        async_run(task);
    end;

    // Wait for asynchronous tasks to end
    sleep(1000);
    disp("done");
endfunction

// Utility function to run a function asynchronously
function async_run(task)
    execstr("task();", "n");
endfunction

// Run main function
main();

Suppose we have a function call f(from). Here’s how we’d call that in the usual way, running it synchronously.

f("direct");

To invoke this function asynchronously in Scilab, we use a construct to simulate goroutines since Scilab does not have built-in support for concurrent execution. Here is how we can schedule these tasks:

tasks = [];
task = function() f("goroutine"); endfunction;
tasks = [tasks, task];
task = function() disp("going"); endfunction;
tasks = [tasks, task];

for task = tasks
    async_run(task);
end;

Our two function calls are running asynchronously now. Wait for them to finish:

sleep(1000);
disp("done");

When we run this program, we see the output of the blocking call first, then the output of the two asynchronous tasks. The output may be interleaved because tasks are being run asynchronously.

direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done

Next, we’ll look at a complement to asynchronous tasks in concurrent programs: communication between tasks.