Goroutines in Julia

Our goal is to demonstrate how to use lightweight threads of execution through the example.

A “goroutine” is a lightweight thread of execution.

You can run this code in Julia as shown below.

using Base.Threads

function f(from::String)
    for i in 0:2
        println(from, " :", i)
    end
end

function 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 thread, use @spawn f(s). This new thread will execute concurrently with the calling one.
    task = @spawn f("thread")

    # You can also start a thread for an anonymous function call.
    task2 = @spawn begin
        println("going")
    end

    # Our two function calls are running asynchronously in separate threads now. Wait for them to finish
    sleep(1)
    println("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 thread, use @spawn f(s). This new thread will execute concurrently with the calling one.

task = @spawn f("thread")

You can also start a thread for an anonymous function call.

task2 = @spawn begin
    println("going")
end

Our two function calls are running asynchronously in separate threads now. Wait for them to finish (for a more robust approach, consider a more sophisticated method of synchronization).

sleep(1)
println("done")

When we run this program, we see the output of the blocking call first, then the output of the two threads. The threads’ output may be interleaved, because threads are being run concurrently by the Julia runtime.

$ julia goroutines.jl
direct : 0
direct : 1
direct : 2
thread : 0
going
thread : 1
thread : 2
done

Next, we’ll look at a complement to threads in concurrent Julia programs: channels.