Feature Request: std::sync::Latch or std::sync::WaitGroup

Maybe we can have a std::sync::Latch?

As far as I know, C++ added std::latch (with std::barrier) in C++ 20. Most languages also have the same or similar structures/classes.

It is a downward counter which can be used to synchronize threads. It looks like a single-use barrier because the counter doesn't reset after reaching 0. Instead, it has a useful property that it doesn't require that threads calling count_down() wait for the counter to reach 0 before proceeding. This also means that it can be decremented by a participating thread more than once.

The most popular implementation of latch is solved around atomic integers, e.g. futex atomic wait (in GNU C++), or atomic + wait queue (in Java). Of course there are different examples here, e.g. concurrent-ruby uses mutex.

Personally, I often use it in benchmarks involving multi-threaded tasks, as its count_down() is typically within 3-10 nanoseconds, with negligible impact on benchmarks. It also provides capabilities similar to join_all(threads) with concurrency instead of looping over Vec<JoinHandle<T>>, or a signal gate that begin operating "simultaneously".

3 Likes

Are there extant implementations on crates.io? Can we get a survey of how much any of them are used to help gauge how much of an impact it being in the stdlib would be?

I'm not sure the list below is exhaustive, there are some examples:

  • waitgroup, wait-group variant async impl, 1,915,944 downloads.
  • wg, wait-group variant, 143,030 downloads.
  • awaitgroup, wait-group variant async impl, 71,330 downloads.
  • wait-for-me, async impl, 12,294 downloads.
  • wait_group, wait-group variant, 4,675 downloads.
  • sync-wait-group, wait-group variant, 1,137 downloads.
  • countdown_latch, sync impl, 565 downloads.
  • latches, sync/async impl, 101 downloads.

About "wait-group variant": this may be a personal opinion, although WaitGroup and latch look different, their applicable scenarios are almost the same.

As for choosing WaitGroup or Latch, I think this is opinion-based. Golang/C# chooses WaitGroup (C# names it CountdownEvent), C++/Java chooses latch/CountDownLatch

3 Likes

There's also crossbeam::sync::WaitGroup, though it's a bit harder to know how many people are actually using it.

3 Likes

If we're adding new synchronization primitives, what about semaphores and events.

There was a sync semaphore but it was removed (link to issue). tokio has semaphores and they can extremely useful (though usually you can achieve whatever you're trying to do with a semaphore with a bounded channel instead).

2 Likes