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.
// 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 }
task C running task C done task A running task A done task B running task B done all tasks completed
How it works
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 (5, 10 and 20 milliseconds). 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.