Sobes.tech
Назад к вопросам
Senior
5

Какие паттерны конкурентного программирования ты знаешь?

Компании, где спрашивали
.wrk

Ответ от нейросети

sobes.tech AI

В конкурентном программировании часто применяются следующие паттерны:

  • Producer-Consumer (Производитель-Потребитель) — разделение потоков на тех, кто производит данные, и тех, кто их потребляет, с использованием буферов или очередей.
  • Mutex (Взаимное исключение) — для защиты общих ресурсов от одновременного доступа.
  • Read-Write Lock (Чтение-запись) — позволяет нескольким потокам читать данные одновременно, но запись — только одному.
  • Future/Promise — для асинхронного получения результата вычисления.
  • Thread Pool (Пул потоков) — ограничение количества одновременно работающих потоков.
  • Barrier (Барьер) — синхронизация нескольких потоков, чтобы они достигли определённой точки вместе.
  • Lock-Free и Wait-Free алгоритмы — для минимизации блокировок и повышения производительности.
  • Event Loop (Цикл событий) — обработка событий в одном потоке с асинхронными вызовами.

Пример паттерна Producer-Consumer на C++ с использованием std::mutex и 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;
}

Этот пример демонстрирует классический паттерн, где производитель и потребитель синхронизируются через условную переменную и мьютекс.