Waitgroups in Nim

Our first example demonstrates how to use a CountdownLatch to wait for multiple threads to finish. This is similar to the concept of WaitGroups in other languages.

import std/[threadpool, locks, os]

# This is the function we'll run in every thread.
proc worker(id: int) =
  echo "Worker ", id, " starting"
  # Sleep to simulate an expensive task.
  sleep(1000)
  echo "Worker ", id, " done"

# Create a CountdownLatch
var latch: CountdownLatch

proc main() =
  # Initialize the CountdownLatch with the number of workers
  latch.initCountdownLatch(5)

  # Launch several threads and decrement the CountdownLatch
  # counter for each.
  for i in 1..5:
    spawn (proc () =
      worker(i)
      latch.countDown()
    )()

  # Block until the CountdownLatch counter goes back to 0;
  # all the workers notified they're done.
  latch.wait()

  # Note that this approach has no straightforward way
  # to propagate errors from workers. For more
  # advanced use cases, consider using other synchronization
  # primitives or error handling mechanisms.

main()

To run the program:

$ nim c -r waitgroups.nim
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.

In this Nim example, we use the threadpool module to spawn threads, which is similar to launching goroutines. The CountdownLatch from the locks module serves a similar purpose to the WaitGroup in the original example.

We define a worker procedure that simulates some work by sleeping for a second. In the main procedure, we initialize a CountdownLatch with a count of 5 (the number of workers we’ll spawn).

We then use a loop to spawn 5 threads, each running an anonymous procedure that calls worker and then decrements the latch counter using countDown().

Finally, we call latch.wait(), which blocks until the latch counter reaches zero, indicating that all workers have finished.

Note that Nim’s approach to concurrency is different from some other languages, and it doesn’t have a direct equivalent to goroutines. However, the threadpool module provides a way to work with threads in a somewhat similar manner.