/*

Atomic variables are those that can be accessed or modified by multiple threads simultaneously without causing data races. 
The std::atomic<T> template is used to declare atomic variables in C++. Operations on atomic variables are indivisible (atomic), 
meaning that no other thread can observe the variable in an intermediate state.

*/

#include <iostream>
#include <thread>
#include <atomic>
#include <vector>

std::atomic<int> atomicCounter(0);  // Declare an atomic counter

// Function to be run by multiple threads
void incrementCounter() {
    for (int i = 0; i < 1000; ++i) {
        atomicCounter++;  // Atomically increment the counter
    }
}

int main() {
    std::vector<std::thread> threads;

    // Create 10 threads
    for (int i = 0; i < 10; ++i) {
        threads.push_back(std::thread(incrementCounter));
    }

    // Wait for all threads to finish
    for (auto& th : threads) {
        th.join();
    }

    std::cout << "Final counter value: " << atomicCounter << std::endl;
    return 0;
}


/*

Explanation:
In multi-threaded programs, data races occur when two or more threads access the same variable concurrently, and at least one of them
is modifying it. Without proper synchronization, the program might behave unpredictably.

To prevent data races, C++ provides the std::atomic template, which ensures that operations on the variable are atomic. This means that
the operation will be completed in a single, uninterruptible step. No other thread can observe the variable in an intermediate state
during an atomic operation.

Example:
Suppose you have a program where multiple threads need to increment a shared counter. If you use a regular int variable, you might
encounter a race condition because threads might read and write to the counter simultaneously.

Explanation of the Example:
Atomic Variable Declaration:

std::atomic<int> atomicCounter(0); declares an atomic integer variable initialized to 0.
Thread Function (incrementCounter):

This function runs in multiple threads. It contains a loop that increments the atomic counter 1000 times.
The operation atomicCounter++ is atomic, ensuring that the counter is safely incremented even when multiple threads execute 
this statement concurrently.

Main Function:

We create 10 threads, each running the incrementCounter function.
Each thread will increment the atomic counter 1000 times.
After all threads finish executing, we print the final value of atomicCounter.
Why Atomic Matters:
Without using std::atomic, if we used a regular int for atomicCounter, the final output might not be 10000. This is because of potential
race conditions where multiple threads could read and write to the counter simultaneously, causing some increments to be lost.

By using std::atomic, we ensure that every increment operation is completed without interruption, leading to the correct and expected
final result of 10000.

*/

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: