Nyx by Example

WaitGroup

WaitGroup from std/sync coordinates multiple threads. wg_add sets the expected count, each thread calls wg_done when finished, and wg_wait blocks until the count reaches zero.

Code

// WaitGroup — waiting for multiple threads to finish
// WaitGroup — esperar a que múltiples hilos terminen

import "std/sync"

var wg: WaitGroup = wg_new()

fn task_a() -> int {
    print("task A running")
    sleep(10)
    print("task A done")
    wg_done(wg)
    return 0
}

fn task_b() -> int {
    print("task B running")
    sleep(20)
    print("task B done")
    wg_done(wg)
    return 0
}

fn task_c() -> int {
    print("task C running")
    sleep(5)
    print("task C done")
    wg_done(wg)
    return 0
}

fn main() -> int {
    // Set the counter to the number of tasks
    wg_add(wg, 3)

    // Spawn three concurrent tasks
    thread_spawn(task_a)
    thread_spawn(task_b)
    thread_spawn(task_c)

    // Block until all three call wg_done()
    wg_wait(wg)
    print("all tasks completed")
    return 0
}

Output

task C running
task C done
task A running
task A done
task B running
task B done
all tasks completed

Explanation

WaitGroup is imported from std/sync. It maintains an internal counter: wg_add(wg, 3) sets it to 3, each wg_done call decrements it by 1, and wg_wait blocks until the counter reaches zero.

Three tasks run concurrently with different sleep durations (5ms, 10ms, 20ms). Task C finishes first because it sleeps the least. The exact ordering of output depends on thread scheduling, but "all tasks completed" always prints last because wg_wait guarantees all threads have called wg_done.

This pattern is ideal when you need to fan out work to multiple threads and wait for all of them to complete before proceeding. Unlike thread_join, you don't need to track individual thread handles.

← Previous Next →

Source: examples/by-example/61-waitgroup.nx