C++ barrier::arrive() Function



The std::barrier::arrive() function in C++, is a synchronization mechanism introduced in C++20 that helps to coordinate multiple threads. It provides a way for threads to reach a specific point in execution.

When a thread calls arrive(), it signals that it has reached the barrier. The barrier waits until a predefined number of threads have called arrive(), then proceeds to release all waiting threads simultaneously, allowing them to continue execution.

Syntax

Following is the syntax for std::barrier::arrive() function.

arrival_token arrive( std::ptrdiff_t n = 1 );

Parameters

  • n − It indicates the value by which the expected count is decreased.

Return value

This function returns the constructed arrival_token object.

Exception

It throws std::system_error with an error code allowed for mutex types on error.

Example 1

In the following example, we are going to use the arrive() to signal the completion of each thread work before they proceed to next phase.

#include <iostream>
#include <thread>
#include <barrier>
#include <vector>
void x(std::barrier < > & sync_point, int y) {
   std::cout << "Thread " << y << " started working.\n";
   std::this_thread::sleep_for(std::chrono::milliseconds(200 * y));
   std::cout << "Thread " << y << " completed work and arrives.\n";
   sync_point.arrive();
}
int main() {
   const int a = 2;
   std::barrier sync_point(a);
   std::vector < std::thread > b;
   for (int i = 0; i < a; ++i) {
      b.emplace_back(x, std::ref(sync_point), i + 1);
   }
   for (auto & t: b) {
      t.join();
   }
   std::cout << "All threads arrived at the barrier.\n";
   return 0;
}

Output

Output of the above code is as follows −

Thread 2 started working.
Thread 1 started working.
Thread 1 completed work and arrives.
Thread 2 completed work and arrives.
All threads arrived at the barrier.

Example 2

Consider the following example, where we are going to split the task into phases and each phase requires threads to arrive at the barrier before proceeding.

#include <iostream>
#include <thread>
#include <barrier>
void a(std::barrier < > & sync_point, int b) {
   std::cout << "Starting phase " << b << "\n";
   sync_point.arrive();
   std::cout << "Finished phase " << b << "\n";
}
int main() {
   std::barrier sync_point(2);
   for (int i = 0; i < 2; ++i) {
      std::thread(a, std::ref(sync_point), i + 1).detach();
   }
   std::this_thread::sleep_for(std::chrono::seconds(1));
   return 0;
}

Output

Following is the output of the above code −

Starting phase 1
Finished phase 1
Starting phase 2
Finished phase 2
cpp_barrier.htm