cpp

examples

examples.cpp⚙️
/**
 * Multithreading - Examples
 * Compile: g++ -std=c++17 -pthread -Wall examples.cpp -o examples
 */

#include <iostream>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <condition_variable>
#include <future>
#include <atomic>
#include <vector>
#include <queue>
#include <chrono>
using namespace std;

// ============================================================
// SECTION 1: BASIC THREADS
// ============================================================

void simpleTask(int id) {
    cout << "  Thread " << id << " running" << endl;
    this_thread::sleep_for(chrono::milliseconds(100));
    cout << "  Thread " << id << " done" << endl;
}

void demoBasicThreads() {
    cout << "--- Basic Threads ---\n" << endl;
    
    cout << "  Hardware threads: " << thread::hardware_concurrency() << endl;
    
    // Create threads
    thread t1(simpleTask, 1);
    thread t2(simpleTask, 2);
    
    // Lambda thread
    thread t3([]() {
        cout << "  Lambda thread running" << endl;
    });
    
    // Wait for completion
    t1.join();
    t2.join();
    t3.join();
    
    cout << "  All threads complete" << endl;
}

// ============================================================
// SECTION 2: MUTEX
// ============================================================

mutex printMutex;
int unsafeCounter = 0;
int safeCounter = 0;
mutex counterMutex;

void unsafeIncrement() {
    for (int i = 0; i < 10000; i++) {
        unsafeCounter++;
    }
}

void safeIncrement() {
    for (int i = 0; i < 10000; i++) {
        lock_guard<mutex> lock(counterMutex);
        safeCounter++;
    }
}

void demoMutex() {
    cout << "\n--- Mutex ---\n" << endl;
    
    // Unsafe (race condition)
    unsafeCounter = 0;
    vector<thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.emplace_back(unsafeIncrement);
    }
    for (auto& t : threads) t.join();
    cout << "  Unsafe counter: " << unsafeCounter 
         << " (expected 100000)" << endl;
    
    // Safe (with mutex)
    threads.clear();
    safeCounter = 0;
    for (int i = 0; i < 10; i++) {
        threads.emplace_back(safeIncrement);
    }
    for (auto& t : threads) t.join();
    cout << "  Safe counter: " << safeCounter << endl;
}

// ============================================================
// SECTION 3: UNIQUE_LOCK
// ============================================================

mutex flexMutex;

void demoUniqueLock() {
    cout << "\n--- unique_lock ---\n" << endl;
    
    unique_lock<mutex> lock(flexMutex);
    cout << "  Lock acquired" << endl;
    
    // Can release and reacquire
    lock.unlock();
    cout << "  Lock released" << endl;
    
    // Do something without lock...
    
    lock.lock();
    cout << "  Lock reacquired" << endl;
    
    // Deferred locking
    unique_lock<mutex> lock2(flexMutex, defer_lock);
    cout << "  Deferred lock created (not locked yet)" << endl;
    lock2.lock();
    cout << "  Deferred lock now locked" << endl;
}

// ============================================================
// SECTION 4: CONDITION VARIABLE
// ============================================================

mutex cvMutex;
condition_variable cv;
bool dataReady = false;
string sharedData;

void producer() {
    this_thread::sleep_for(chrono::milliseconds(500));
    {
        lock_guard<mutex> lock(cvMutex);
        sharedData = "Data from producer";
        dataReady = true;
    }
    cv.notify_one();
}

void consumer() {
    unique_lock<mutex> lock(cvMutex);
    cv.wait(lock, []{ return dataReady; });
    cout << "  Consumer received: " << sharedData << endl;
}

void demoConditionVariable() {
    cout << "\n--- Condition Variable ---\n" << endl;
    
    dataReady = false;
    thread prod(producer);
    thread cons(consumer);
    
    prod.join();
    cons.join();
}

// ============================================================
// SECTION 5: PRODUCER-CONSUMER QUEUE
// ============================================================

queue<int> taskQueue;
mutex queueMutex;
condition_variable queueCV;
bool finished = false;

void producerTask() {
    for (int i = 1; i <= 5; i++) {
        {
            lock_guard<mutex> lock(queueMutex);
            taskQueue.push(i);
            cout << "  Produced: " << i << endl;
        }
        queueCV.notify_one();
        this_thread::sleep_for(chrono::milliseconds(100));
    }
    {
        lock_guard<mutex> lock(queueMutex);
        finished = true;
    }
    queueCV.notify_all();
}

void consumerTask(int id) {
    while (true) {
        unique_lock<mutex> lock(queueMutex);
        queueCV.wait(lock, []{ return !taskQueue.empty() || finished; });
        
        if (taskQueue.empty() && finished) break;
        
        int val = taskQueue.front();
        taskQueue.pop();
        lock.unlock();
        
        cout << "  Consumer " << id << " processed: " << val << endl;
    }
}

void demoProducerConsumer() {
    cout << "\n--- Producer-Consumer ---\n" << endl;
    
    // Reset state
    while (!taskQueue.empty()) taskQueue.pop();
    finished = false;
    
    thread prod(producerTask);
    thread cons1(consumerTask, 1);
    thread cons2(consumerTask, 2);
    
    prod.join();
    cons1.join();
    cons2.join();
}

// ============================================================
// SECTION 6: ASYNC AND FUTURES
// ============================================================

int heavyComputation(int n) {
    cout << "  Computing in thread " << this_thread::get_id() << endl;
    this_thread::sleep_for(chrono::milliseconds(500));
    return n * n;
}

void demoAsync() {
    cout << "\n--- Async and Futures ---\n" << endl;
    
    cout << "  Main thread: " << this_thread::get_id() << endl;
    
    // Launch async task
    future<int> result1 = async(launch::async, heavyComputation, 5);
    future<int> result2 = async(launch::async, heavyComputation, 10);
    
    cout << "  Doing other work while computing..." << endl;
    
    // Get results (blocks if not ready)
    cout << "  Result 1: " << result1.get() << endl;
    cout << "  Result 2: " << result2.get() << endl;
}

// ============================================================
// SECTION 7: PROMISE AND FUTURE
// ============================================================

void workerWithPromise(promise<string> p) {
    this_thread::sleep_for(chrono::milliseconds(300));
    p.set_value("Result from worker");
}

void demoPromise() {
    cout << "\n--- Promise and Future ---\n" << endl;
    
    promise<string> p;
    future<string> f = p.get_future();
    
    thread t(workerWithPromise, move(p));
    
    cout << "  Waiting for result..." << endl;
    string result = f.get();
    cout << "  Got: " << result << endl;
    
    t.join();
}

// ============================================================
// SECTION 8: ATOMIC OPERATIONS
// ============================================================

atomic<int> atomicCounter(0);

void atomicIncrement() {
    for (int i = 0; i < 10000; i++) {
        atomicCounter++;
    }
}

void demoAtomic() {
    cout << "\n--- Atomic Operations ---\n" << endl;
    
    atomicCounter = 0;
    
    vector<thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.emplace_back(atomicIncrement);
    }
    for (auto& t : threads) t.join();
    
    cout << "  Atomic counter: " << atomicCounter << endl;
    
    // Atomic operations
    atomicCounter.store(100);
    cout << "  After store(100): " << atomicCounter.load() << endl;
    
    int old = atomicCounter.exchange(200);
    cout << "  Exchange returned: " << old << ", new value: " 
         << atomicCounter << endl;
    
    // Compare and swap
    int expected = 200;
    bool success = atomicCounter.compare_exchange_strong(expected, 300);
    cout << "  CAS success: " << boolalpha << success 
         << ", value: " << atomicCounter << endl;
}

// ============================================================
// MAIN
// ============================================================

int main() {
    cout << "╔══════════════════════════════════════╗" << endl;
    cout << "║    MULTITHREADING - EXAMPLES         ║" << endl;
    cout << "╚══════════════════════════════════════╝" << endl;
    
    demoBasicThreads();
    demoMutex();
    demoUniqueLock();
    demoConditionVariable();
    demoProducerConsumer();
    demoAsync();
    demoPromise();
    demoAtomic();
    
    cout << "\n=== Complete ===" << endl;
    return 0;
}
Examples - C++ Tutorial | DeepML