Demonstration of Race Condition and Its Solution Using Mutex
1. Aim
To demonstrate a race condition in a multithreaded program and to eliminate it using a mutex for proper synchronization.

2. Objectives
To understand race conditions in multithreading

To observe incorrect results due to unsynchronized access

To apply mutex locks to ensure mutual exclusion

To compare behavior with and without synchronization

3. Theory
Race Condition
A race condition occurs when:

Two or more threads access shared data

At least one thread modifies it

Execution order is unpredictable

This results in incorrect or inconsistent output.

Mutex (Mutual Exclusion)
A mutex ensures:

Only one thread can access a critical section at a time

Prevents simultaneous updates to shared data

4. Problem Description
Create two threads:

Each thread adds two numbers

Both threads update a shared global variable

Observe incorrect output (race condition)

Fix the issue using a mutex

5. Algorithm
Part A: Without Synchronization (Race Condition)
Declare a shared variable total_sum

Create two threads

Each thread adds its numbers to total_sum

Main thread prints the result

Part B: With Synchronization (Mutex)
Initialize a mutex

Lock the mutex before updating total_sum

Unlock mutex after update

Print the correct result

6. Program – Part A: Race Condition (Without Mutex)
#include <stdio.h>
#include <pthread.h>

int total_sum = 0;   // Shared resource

void *add(void *arg) {
    int *arr = (int *)arg;
    int local_sum = arr[0] + arr[1];

    // Critical section (UNPROTECTED)
    total_sum += local_sum;

    return NULL;
}

int main() {
    pthread_t t1, t2;

    int a[2] = {10, 20};
    int b[2] = {15, 25};

    pthread_create(&t1, NULL, add, a);
    pthread_create(&t2, NULL, add, b);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Final Sum (Without Mutex) = %d\n", total_sum);

    return 0;
}
Observation (Without Mutex)
binuvp@debian-workstation:~$ ./a.out

Final Sum (Without Mutex) = 30

binuvp@debian-workstation:~$ ./a.out

Final Sum (Without Mutex) = 70

binuvp@debian-workstation:~$ ./a.out

Final Sum (Without Mutex) = 70

➡ Output varies due to race condition

7. Program – Part B: Race Condition Solved Using Mutex
#include <stdio.h>
#include <pthread.h>

int total_sum = 0;
pthread_mutex_t lock;

void *add(void *arg) {
    int *arr = (int *)arg;
    int local_sum = arr[0] + arr[1];

    pthread_mutex_lock(&lock);   // Enter critical section
    total_sum += local_sum;
    pthread_mutex_unlock(&lock); // Exit critical section

    return NULL;
}

int main() {
    pthread_t t1, t2;

    int a[2] = {10, 20};
    int b[2] = {15, 25};

    pthread_mutex_init(&lock, NULL);

    pthread_create(&t1, NULL, add, a);
    pthread_create(&t2, NULL, add, b);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Final Sum (With Mutex) = %d\n", total_sum);

    pthread_mutex_destroy(&lock);

    return 0;
}
8. Compilation & Execution
gcc race_condition.c -lpthread
9. Sample Output
binuvp@debian-workstation:~$ ./a.out
Final Sum (With Mutex) = 70
10. Observations
Case	                Result
Without mutex	                Incorrect / inconsistent
With mutex	                Correct and consistent
11. Result
The experiment successfully demonstrated a race condition due to unsynchronized access to shared data.
Using a mutex, mutual exclusion was enforced and the race condition was eliminated.
