Saturday, January 20, 2024

The Barrier in C++ 20 concurrency - the programmer in me is still thriving...

Enjoy my training video on the C++ barrier...


The std::barrier class is a synchronization primitive introduced in C++20. It allows a set of threads to synchronize at a certain point in their execution. It is similar to the std::latch class, but it can be reused multiple times.

A std::barrier object is initialized with a count, which specifies the number of threads that must reach the barrier before any of them can proceed. When a thread reaches the barrier, it calls the wait() method. If the count is not yet zero, the thread will be blocked until the count reaches zero. Once the count reaches zero, all of the threads that are waiting on the barrier will be released and can proceed.

The std::barrier class can be used to implement a variety of synchronization patterns, such as producer-consumer queues, parallel algorithms, and race condition prevention.

Here's my application in which I used barrier to showcase how it can be used.

Class Student

/*

* Student.h

*

* Created on: Jan 10, 2024

* Author: som

*/


#ifndef STUDENT_H_

#define STUDENT_H_



#include <iostream>

#include <string>

#include <thread>

#include <barrier>


using namespace std;



class Student {


private:

string name;

int timeLapseBeforeStarting;

int timeToFinish;


public:

Student(string name, int timeLapseBeforeStarting, int timeToFinish){

this->name = name;

this->timeLapseBeforeStarting = timeLapseBeforeStarting;

this->timeToFinish = timeToFinish;


}

virtual ~Student(){


}


void task(barrier<> &b){


this_thread::sleep_for(chrono::milliseconds(timeLapseBeforeStarting));


b.arrive_and_wait();


const auto now = std::chrono::system_clock::now();


const std::time_t t_c = std::chrono::system_clock::to_time_t(now);


cout<< this-> name << " is Starting the task at " << std::ctime(&t_c);


this_thread::sleep_for(chrono::milliseconds(timeToFinish));


cout<< this-> name <<" finished the task"<<endl;


}

};


#endif /* STUDENT_H_ */


Class classETC

/*

* classETC.h

*

* Created on: Jan 10, 2024

* Author: som

*/


#ifndef CLASSETC_H_

#define CLASSETC_H_


#include <thread>

#include <barrier>

#include "Student.h"


using namespace std;


class classETC {


public:

classETC(){


}

virtual ~classETC(){


}


auto giveTaskToStudent(barrier<> &b){

thread riditT(&Student::task, new Student ("Ridit", 1000,2000), ref(b));

thread ishanT(&Student::task, new Student("Ishan", 3000, 1000), ref(b));

thread rajdeepT(&Student::task, new Student("Rajdeep", 900, 1500), ref(b));


riditT.join();

ishanT.join();

rajdeepT.join();

}

};





#endif /* CLASSETC_H_ */



The Main method


//============================================================================

// Name : BarrierC++.cpp

// Author : som

// Version :

// Copyright : som-itsolutions

// Description : Hello World in C++, Ansi-style

//============================================================================


// C++ Program to demonstrate use of use std::barrier in

#include <iostream>

#include <barrier>

#include <thread>


#include "classETC.h"


using namespace std;



int main() {


cout << "C++ Version" << endl; // prints C++ Version

if (__cplusplus == 202101L)

cout << "C++23";

else if(__cplusplus == 202002L)

cout << "C++20\n";

else if (__cplusplus == 201703L)

cout << "C++17\n";

else if (__cplusplus == 201402L)

cout << "C++14\n";

else if (__cplusplus == 201103L)

cout << "C++11\n";

else if (__cplusplus == 199711L)

cout << "C++98\n";

else cout << "pre-standard C++\n";


barrier b ( 3);


classETC etc;


etc.giveTaskToStudent(b);





return 0;

}


The Output:


C++ Version C++20 Ishan is Starting the task at RiditRajdeep is Starting the task at is Starting the task at Sat Jan 20 17:41:30 2024 Sat Jan 20 17:41:30 2024 Sat Jan 20 17:41:30 2024 Ishan finished the task Rajdeep finished the task Ridit finished the task

Have a look at the time when the three different threads are starting - all of them start at the
same time - 17:41:30 - why?
As you have guessed it correctly - it's because of the barrier.
Enjoy...


No comments: