Latches and Barriers
Latches and barriers are simple thread synchronization mechanisms which enable some threads to wait until a counter becomes zero. At first, don’t confuse the new barriers with memory barriers (also known as fences). In C++20, we will presumably get latches and barriers in three variations:
First, there are two questions:
- What are the differences between these three mechanisms to synchronize threads? You can use an
std::latchonly once, but you can use an
std::flex_barriermore than once. Additionally, an
std::flex_barrierenables you to execute a function when the counter becomes zero.
- What use cases do latches and barriers support that cannot be done in C++11 and C++14 with futures, threads, or condition variables in combination with locks? Latches and barriers address no new use cases, but they are a lot easier to use; they are also more performant because they often use a lock-free mechanism internally.
Now, I will have a closer look at these three coordination mechanisms.
std::latch is a countdown counter; its value is set in the constructor. A thread can decrement the counter by using the method
thread.count_down_and_wait and wait until the counter becomes zero. In addition, the method
thread.count_down only decrements the counter by 1 without waiting.
std::latch also has the method
thread.is_ready that can be used to test if the counter is zero, and the method
thread.wait to wait until the counter becomes zero. You cannot increment or reset the counter of a
std::latch, hence you cannot reuse it.
Here is a short code snippet from the N4204 proposal: