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