Waitgroups in Julia

Our example demonstrates how to wait for multiple tasks to finish using Threads in Julia. This is similar to the concept of WaitGroups in other languages.

using Printf

# This is the function we'll run in every task
function worker(id)
    @printf("Worker %d starting\n", id)
    
    # Sleep to simulate an expensive task
    sleep(1)
    @printf("Worker %d done\n", id)
end

function main()
    # Create an array to store our tasks
    tasks = []

    # Launch several tasks
    for i in 1:5
        # Wrap the worker call in a task
        task = @async worker(i)
        push!(tasks, task)
    end

    # Wait for all tasks to finish
    for task in tasks
        wait(task)
    end
end

# Run the main function
main()

In this Julia program:

  1. We define a worker function that simulates some work by sleeping for a second.

  2. In the main function, we create an array to store our tasks.

  3. We launch several tasks using a for loop and the @async macro, which is Julia’s way of creating asynchronous tasks (similar to goroutines).

  4. We then wait for all tasks to finish using another for loop and the wait function.

To run the program, save it as waitgroups.jl and use the Julia REPL:

$ julia waitgroups.jl
Worker 1 starting
Worker 2 starting
Worker 3 starting
Worker 4 starting
Worker 5 starting
Worker 1 done
Worker 2 done
Worker 3 done
Worker 4 done
Worker 5 done

The order of workers starting up and finishing is likely to be different for each invocation.

Note that Julia’s approach to concurrency is different from some other languages. It uses a task-based parallelism model, which is lightweight and efficient. The @async macro creates these tasks, and the wait function allows us to wait for their completion.

For more advanced use cases, Julia provides additional synchronization primitives like Channels and Conditions, as well as distributed computing capabilities.