C++ Basics: Wait for a Batch with std::latch
Publish independent result slots and wait until a fixed batch has reported completion.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable GCC compiler and its standard-library development files, with g++ on PATH. You also need Bash, a text editor, and mktemp, rm, and rmdir. No third-party library is required.
Keep the same terminal open. Stop if setup fails before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as latch-batch-completion-demo.cpp:
#include <array>
#include <cstddef>
#include <iostream>
#include <latch>
#include <thread>
#include <vector>
int main()
{
std::array<int, 3> results{};
std::latch completed{3};
std::vector<std::jthread> workers;
workers.reserve(results.size());
for (std::size_t result_index = 0; result_index < results.size(); ++result_index) {
workers.emplace_back([&, result_index] {
results[result_index] = static_cast<int>((result_index + 1) * 10);
completed.count_down();
});
}
completed.wait();
std::cout << "Results: " << results[0] << ' '
<< results[1] << ' ' << results[2] << '\n';
for (auto& worker : workers) {
worker.join();
}
}Compile and run it. The second command runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic -pthread latch-batch-completion-demo.cpp -o latch-batch-completion-demo &&
./latch-batch-completion-demoObserved output:
Results: 10 20 30Read the result
Each worker writes a different array element, then decrements the latch. When wait returns, all three preceding result writes are visible to main. Printing happens in main rather than in workers, so scheduling cannot rearrange the output. The explicit joins also ensure thread completion before local objects are destroyed.
Apply it carefully
A latch is single-use and cannot be reset for a second batch. Its initial count must match the number of completion reports. This example has nonthrowing worker work; real tasks must report completion even when their work fails, while preserving the failure for the caller. A latch coordinates completion but does not protect workers that write the same result slot.
The C++ working draft documents the relevant rules. This example uses C++20 facilities; the current draft also contains newer additions.
Clean up
Remove only the source and executable created here, then remove the empty practice directory:
rm -- latch-batch-completion-demo.cpp latch-batch-completion-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.