cpp
exercises
exercises.cpp⚙️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; });
}
}
};
*/