← Назад к вопросам

Какие знаешь способы синхронизации?

1.7 Middle🔥 191 комментариев
#Многопоточность и синхронизация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы синхронизации в C/C++

Синхронизация — критически важна для многопоточного программирования, где несколько потоков обращаются к общим ресурсам. Расскажу об основных механизмах:

1. Мьютексы (Mutex)

Мьютекс — самый базовый примитив синхронизации. Обеспечивает взаимное исключение: только один поток может держать блокировку одновременно.

#include <mutex>
#include <thread>

std::mutex mtx;
int shared_counter = 0;

void increment() {
    std::lock_guard<std::mutex> lock(mtx);
    ++shared_counter;
}

Типы мьютексов:

  • std::mutex — обычный мьютекс
  • std::recursive_mutex — рекурсивный (один поток может захватить несколько раз)
  • std::timed_mutex — с timeout
  • std::shared_mutex — для читателей-писателей

2. Условные переменные (Condition Variables)

Позволяют потокам ждать конкретного условия, экономя CPU:

#include <condition_variable>

std::condition_variable cv;
std::mutex mtx;
bool ready = false;

std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; });

ready = true;
cv.notify_one();

3. Семафоры (Semaphore - C++20)

Контролируют доступ к пулу ресурсов:

#include <semaphore>

std::counting_semaphore<3> sem(3);

void worker() {
    sem.acquire();
    sem.release();
}

4. Атомарные операции (Atomics)

Для простых операций без блокировок:

#include <atomic>

std::atomic<int> counter(0);
counter++;
int val = counter.load(std::memory_order_acquire);

5. Read-Write Locks

Множество читателей или один писатель:

std::shared_mutex rwmtx;
std::shared_lock<std::shared_mutex> lock(rwmtx);

6. Барьеры (C++20)

Синхронизирует группу потоков в точке встречи.

Лучшие практики

Используй RAII:

  • std::lock_guard — для автоматического освобождения
  • std::unique_lock — с отложенной блокировкой
  • Никогда не захватывай/отпускай вручную

Избегай дедлоков:

  • Выстраивай единый порядок захватов
  • Не держи блокировку дольше необходимого
  • Используй std::lock для множественных мьютексов

Выбирай инструмент:

  • Мьютекс — стандартный выбор
  • Atomics — для счётчиков и флагов
  • Condition variables — для ожидания событий
  • RWLock — если много читателей, мало писателей