Подтвердить что ты не робот

Уведомление о событии без мьютекса

С++ 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, но мне не нравится спать.

4b9b3361

Ответ 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 с внутренним мьютексом.

Вам нужно связать хотя бы один бит дополнительной информации с переменной условия, и этот бит должен быть защищен мьютексом.