Data races in C++ multithreaded applications occur when multiple threads try to access a single data without proper data locking tools like mutex.
Causes of Data Races
- Concurrent Reads and Writes: If one thread reads a variable while another writes to it without synchronization, a data race occurs.
- Concurrent Writes: If multiple threads write to the same variable concurrently without synchronization, it leads to a data race.
- Lack of Synchronization Primitives: Not using mutexes, atomic operations, or other synchronization mechanisms can result in data races.
Data race may cause unpredictable output and even crashes.
For example, look at the below C++ programs.
//============================================================================
// Name : C++20Atomic.cpp
// Author : Som
// Version :
// Copyright : som-itsolutions
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <atomic>
#include <thread>
int counter = 0;
void incrementCounter() {
for (int i = 0; i < 10000; ++i) {
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
Here two threads are trying to access a single variable without a proper synchronization technique.
Here is the video in which the program is run in Eclipse.
//============================================================================
// Name : C++20Atomic.cpp
// Author : Som
// Version :
// Copyright : som-itsolutions
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int> counter(0);
void incrementCounter() {
for (int i = 0; i < 10000000; ++i) {
counter++;
}
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}
Enjoy...