Senior
What concurrency patterns do you know?
sobes.tech AI
Answer from AI
In competitive programming, the following patterns are often used:
- Producer-Consumer — dividing threads into those that produce data and those that consume it, using buffers or queues.
- Mutex — for protecting shared resources from concurrent access.
- Read-Write Lock — allows multiple threads to read data simultaneously, but only one to write.
- Future/Promise — for asynchronously obtaining the result of a computation.
- Thread Pool — limiting the number of threads working simultaneously.
- Barrier — synchronizing multiple threads to reach a certain point together.
- Lock-Free and Wait-Free algorithms — to minimize locking and improve performance.
- Event Loop — processing events in a single thread with asynchronous calls.
An example of the Producer-Consumer pattern in C++ using std::mutex and std::condition_variable:
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <iostream>
std::queue<int> buffer;
std::mutex mtx;
std::condition_variable cv;
const unsigned int maxBufferSize = 10;
void producer() {
int data = 0;
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [](){ return buffer.size() < maxBufferSize; });
buffer.push(data++);
std::cout << "Produced: " << data << std::endl;
lock.unlock();
cv.notify_all();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [](){ return !buffer.empty(); });
int data = buffer.front();
buffer.pop();
std::cout << "Consumed: " << data << std::endl;
lock.unlock();
cv.notify_all();
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
}
int main() {
std::thread prod(producer);
std::thread cons(consumer);
prod.join();
cons.join();
return 0;
}
This example demonstrates the classic pattern where producer and consumer synchronize through a condition variable and a mutex.