Какие механизмы синхронизации существуют для решения проблем многопоточности
Что проверяют
Владеете ли вы стандартной библиотекой C++ и понимаете ли, что защищать надо инвариант целиком, а не отдельную переменную. Следом идут два вопроса: как избежать взаимной блокировки и чем std::atomic отличается от мьютекса.
Как отвечать
Перечисляйте примитивы вместе с условиями применения:
std::mutex: базовый замок, захватывать только через RAII:std::lock_guard,std::unique_lock, если нужно отпустить раньше,std::scoped_lockиз C++17, который берёт несколько мьютексов сразу и сам разруливает порядок;std::recursive_mutex: повторный захват тем же потоком. Обычно это симптом того, что публичный метод зовёт другой публичный, а не отдельную приватную реализацию;std::shared_mutex(C++17): много читателей или один писатель, выигрывает при редкой записи; чтение черезstd::shared_lock;std::condition_variable: ожидание условия без активного опроса.waitвызывать только с предикатом из-за ложных пробуждений, менять условие под захваченным мьютексом;std::atomic: счётчики и флаги без блокировок, по умолчаниюmemory_order_seq_cst, ослаблять порядок только с обоснованием; в C++20 добавилисьwaitиnotify_one;- примитивы C++20:
std::counting_semaphoreиbinary_semaphoreдля квот и сигналов,std::latchкак одноразовая точка сбора,std::barrierкак циклическая,std::jthreadсоstop_tokenдля остановки; std::call_onceсonce_flagдля однократной инициализации, хотя локальный статик потокобезопасен начиная с C++11.
Хорошо закончить принципом: самый быстрый мьютекс тот, которого нет. Очередь сообщений, потоко-локальные копии и неизменяемые данные снимают проблему целиком, а блокировку держите короткой и не зовите под ней чужой код.
Где спотыкаются
Показывают ручные lock() и unlock(). Первое же исключение между ними оставляет мьютекс захваченным навсегда.
Берут два мьютекса в разном порядке в разных функциях. Классическая взаимная блокировка, лечится единым порядком захвата или std::scoped_lock.
Зовут cv.wait без предиката и удивляются ложным пробуждениям, либо меняют флаг без мьютекса и теряют уведомление, отправленное между проверкой и засыпанием.