Уведомление о событии без мьютекса
С++ 11 имеет std:: condition_variable, его функция ожидания
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );
Для этого требуется мьютекс.
Насколько я понимаю - его notify_one можно вызывать без синхронизации (я знаю, что идиоматический способ - использовать его с мьютексом).
У меня есть объект, который уже внутренне синхронизирован, поэтому мне не нужен мьютекс, чтобы защитить его. Один поток должен ждать некоторого события, связанного с этим объектом, и другие будут уведомлены.
Как сделать такое уведомление без мьютекса в С++ 11? То есть это легко сделать с условием_переменный, но ему нужен мьютекс. Я думал об использовании поддельного типа мьютекса, но std:: mutex прибивается в интерфейсе ожидания.
Опция заключается в опросе std:: atomic_flag + sleep, но мне не нравится спать.
Ответы
Ответ 1
Используйте std::condition_variable_any
вы можете использовать любой класс с ним, который реализует BasicLockable Концепция.
Учитывая плохое чувство об этом, я проверил реализацию std::condition_variable_any
libС++. Оказывается, он использует простой std::condition_variable
вместе с std::shared_ptr
до std::mutex
, поэтому есть определенная часть накладных расходов, не копая глубже. (Есть еще одна статья здесь, на SO, которая охватывает это, хотя я сначала должен искать это)
В связи с этим я, вероятно, рекомендую переделать ваш случай, чтобы синхронизация выполнялась только с помощью мьютекса, защищающего переменную простого условия.
Ответ 2
В некоторых потоковых моделях (хотя я сомневаюсь в современных) мьютекс необходим для защиты самой переменной условия (а не объекта, который вы синхронизируете) от одновременного доступа. Если переменная условия не была защищена мьютексом, вы можете столкнуться с проблемами в самом условии.
См. Почему переменные функции состояния pthreads требуют мьютекса?
Ответ 3
У меня есть некоторый объект, который уже внутренне синхронизирован - мне не нужен мьютекс, чтобы защитить его. Один поток должен ждать некоторого события, связанного с этим объектом, и другие будут уведомлять.
Если вы не держите мьютекс, ожидающий поток будет пропускать уведомления, независимо от того, используете ли вы condition_variable
или condition_variable_any
с внутренним мьютексом.
Вам нужно связать хотя бы один бит дополнительной информации с переменной условия, и этот бит должен быть защищен мьютексом.