Latches and Barriers
This lesson gives an overview of latches and barriers, predicted to be introduced in C++20.
We'll cover the following...
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: std::latch, std::barrier, and std::flex_barrier.
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 anstd::barrierand anstd::flex_barriermore than once. Additionally, anstd::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
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: