Sobes.tech
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.