C Concurrency: POSIX Threads (pthreads), Mutexes & Race Conditions Masterclass

โšก C (C17 / C23 Standard) ๐ŸŸข Lesson 62 ๐Ÿ“‚ Phase 22: System Programming & Embedded C ๐Ÿ“… 2026 Comprehensive Master Edition
๐Ÿ“Œ Covered in this in-depth guide: POSIX Threads (pthreads) ยท Shared Heap vs Private Stack ยท Race Conditions ยท Mutex Protection (pthread_mutex_t) ยท Deadlocks & Coffman Conditions ยท Atomic Operations

Welcome to Phase 22 (Chapter 62): C Concurrency โ€” POSIX Threads (pthreads), Mutexes & Race Conditions Masterclass! Multithreading enables concurrent execution across multi-core CPUs. In this guide, you will master POSIX threads (`pthreads`), race condition prevention with mutex locks, and deadlock elimination.

1Process Memory vs Thread Memory Model
Multithreaded RAM Memory Architecture: Shared Memory (All Threads Access): Private Thread Memory: โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Global & Static Variables โ”‚ โ”‚ Thread 1 Private Stack โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Heap Memory (malloc/free) โ”‚ โ”‚ Thread 2 Private Stack โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ Executable Code Segment โ”‚ โ”‚ Thread 3 Private Stack โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Shared access to Heap/Globals causes RACE CONDITIONS if un-synchronized!
2Race Condition & Mutex Synchronization Code
C โ€” Thread-Safe Counter with POSIX Mutexโ–ถ Run Code in C Compiler
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS 4
#define ITERATIONS 100000

static long counter = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *worker(void *arg) {
    for (int i = 0; i < ITERATIONS; i++) {
        pthread_mutex_lock(&lock);   // CRITICAL SECTION START
        counter++;                   // Safe increment
        pthread_mutex_unlock(&lock); // CRITICAL SECTION END
    }
    return NULL;
}

int main(void) {
    pthread_t threads[NUM_THREADS];
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, worker, NULL);
    }
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    printf("Final Synchronized Counter: %ld (Expected: %d)\n",
           counter, NUM_THREADS * ITERATIONS);
    pthread_mutex_destroy(&lock);
    return 0;
}
3Technical FAQs

Q1: What is a Race Condition?

Occurs when two or more threads concurrently access shared memory and at least one access is a write, producing non-deterministic bugs.

Q2: What is a Deadlock?

A situation where Thread A holds Lock 1 and waits for Lock 2, while Thread B holds Lock 2 and waits for Lock 1, causing both threads to freeze forever.

Q3: How do you prevent deadlocks in C multithreading?

Always acquire multiple locks in the exact same global lock hierarchy order across all threads in your application.

Q4: What is the difference between pthread_join and pthread_detach?

`pthread_join()` waits for a thread to exit and collects its return value. `pthread_detach()` releases thread resources automatically upon exit.

Q5: What are atomic operations in C11 (<stdatomic.h>)?

Hardware-level atomic instructions (`atomic_fetch_add`) that perform thread-safe variable updates without the overhead of mutex locking.