cpp

exercises

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

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

// ============================================================
// Exercise 1: Parallel Sum ⭐⭐
// ============================================================

// TODO: Sum large array using multiple threads
// Each thread sums a portion, combine results

void exercise1() {
    // vector<int> data(1000000, 1);
    // long sum = parallelSum(data, 4);  // 4 threads
    // sum should be 1000000
    cout << "(Implement parallel sum)" << endl;
}

// ============================================================
// Exercise 2: Thread-Safe Counter ⭐⭐
// ============================================================

// TODO: Create thread-safe counter class with
// increment(), decrement(), get() methods

void exercise2() {
    // ThreadSafeCounter counter;
    // Multiple threads: counter.increment();
    // cout << counter.get();
    cout << "(Implement thread-safe counter)" << endl;
}

// ============================================================
// Exercise 3: Parallel Map ⭐⭐
// ============================================================

// TODO: Apply function to each element in parallel
// parallelMap(vector, func, numThreads)

void exercise3() {
    // vector<int> v = {1, 2, 3, 4, 5};
    // parallelMap(v, [](int& x) { x *= 2; }, 2);
    // v is now {2, 4, 6, 8, 10}
    cout << "(Implement parallel map)" << endl;
}

// ============================================================
// Exercise 4: Thread Pool ⭐⭐⭐
// ============================================================

// TODO: Create simple thread pool
// - Constructor takes number of threads
// - submit(task) returns future
// - Workers wait for tasks

void exercise4() {
    // ThreadPool pool(4);
    // auto f1 = pool.submit([]{ return 1; });
    // auto f2 = pool.submit([]{ return 2; });
    // cout << f1.get() + f2.get();
    cout << "(Implement thread pool)" << endl;
}

// ============================================================
// Exercise 5: Readers-Writers Lock ⭐⭐⭐
// ============================================================

// TODO: Implement using shared_mutex
// Multiple readers OR single writer

void exercise5() {
    // RWLock lock;
    // Readers: lock.readLock(); ... lock.readUnlock();
    // Writers: lock.writeLock(); ... lock.writeUnlock();
    cout << "(Implement readers-writers lock)" << endl;
}

// ============================================================
// Exercise 6: Barrier ⭐⭐⭐
// ============================================================

// TODO: Implement barrier that blocks N threads
// until all have arrived

void exercise6() {
    // Barrier barrier(3);
    // Thread 1: barrier.wait(); // blocks until 3 threads call wait
    // Thread 2: barrier.wait();
    // Thread 3: barrier.wait(); // all released
    cout << "(Implement barrier)" << endl;
}

// ============================================================
// Exercise 7: Async Pipeline ⭐⭐⭐
// ============================================================

// TODO: Create pipeline: stage1 | stage2 | stage3
// Each stage runs async, passes result to next

void exercise7() {
    // auto result = pipeline(input)
    //     .then(stage1)
    //     .then(stage2)
    //     .then(stage3)
    //     .get();
    cout << "(Implement async pipeline)" << endl;
}

// ============================================================
// Exercise 8: Lock-Free Stack ⭐⭐⭐
// ============================================================

// TODO: Implement lock-free stack using atomics
// push() and pop() without locks

void exercise8() {
    // LockFreeStack<int> stack;
    // stack.push(1);
    // stack.push(2);
    // auto val = stack.pop();  // 2
    cout << "(Implement lock-free stack)" << endl;
}

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

int main() {
    cout << "=== Multithreading Exercises ===" << endl;
    
    cout << "\nEx1: Parallel Sum" << endl;
    exercise1();
    
    cout << "\nEx2: Thread-Safe Counter" << endl;
    exercise2();
    
    cout << "\nEx3: Parallel Map" << endl;
    exercise3();
    
    cout << "\nEx4: Thread Pool" << endl;
    exercise4();
    
    cout << "\nEx5: Readers-Writers" << endl;
    exercise5();
    
    cout << "\nEx6: Barrier" << endl;
    exercise6();
    
    cout << "\nEx7: Async Pipeline" << endl;
    exercise7();
    
    cout << "\nEx8: Lock-Free Stack" << endl;
    exercise8();
    
    return 0;
}

// ============================================================
// ANSWERS (Partial)
// ============================================================
/*
Ex1:
long parallelSum(const vector<int>& data, int numThreads) {
    vector<long> partialSums(numThreads);
    vector<thread> threads;
    size_t chunkSize = data.size() / numThreads;
    
    for (int i = 0; i < numThreads; i++) {
        size_t start = i * chunkSize;
        size_t end = (i == numThreads - 1) ? data.size() : start + chunkSize;
        threads.emplace_back([&, i, start, end]() {
            long sum = 0;
            for (size_t j = start; j < end; j++) sum += data[j];
            partialSums[i] = sum;
        });
    }
    for (auto& t : threads) t.join();
    return accumulate(partialSums.begin(), partialSums.end(), 0L);
}

Ex2:
class ThreadSafeCounter {
    mutable mutex mtx;
    int value = 0;
public:
    void increment() { lock_guard<mutex> lock(mtx); ++value; }
    void decrement() { lock_guard<mutex> lock(mtx); --value; }
    int get() const { lock_guard<mutex> lock(mtx); return value; }
};

Ex6:
class Barrier {
    mutex mtx;
    condition_variable cv;
    int count, waiting = 0;
public:
    Barrier(int n) : count(n) {}
    void wait() {
        unique_lock<mutex> lock(mtx);
        if (++waiting == count) {
            waiting = 0;
            cv.notify_all();
        } else {
            cv.wait(lock, [this]{ return waiting == 0; });
        }
    }
};
*/
Exercises - C++ Tutorial | DeepML