Почему переменной состояния требуется блокировка (а значит, и мьютекс)

Переменные условия являются одним из аспектов С++ 11 Я все еще немного борюсь. Из того, что я собрал, переменная состояния очень похожа на семафор.

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

Так зачем нужна переменная состояния? И какие дополнительные функции предоставляются добавлением этого требования?

Ответ 1

Переменные условия обычно используются для сигнализации об изменении состояния. Обычно требуется мьютекс, чтобы сделать это изменение, и следующий сигнал, атомный.

Семафор инкапсулирует некоторое состояние (флаг или счетчик) вместе с механизмом сигнализации. Переменная условия более примитивна, только обеспечивая сигнал.

Ответ 2

Как правило, после того, как вы указали, что что-то изменилось (через переменную условия), вам нужно выполнить некоторый код для обработки этого изменения, и этот код должен безопасно читать измененные данные. Если у вас не было блокировки, связанной с cv, тогда ваш поток, ожидающий на cv, может проснуться, тогда попробуйте (и не удастся) получить блокировку, связанную с данными, и, следовательно, придется снова уступить. С помощью комбинации CV/Lock базовая система может разбудить вашу нить только в том случае, если поток может получить соответствующую блокировку в качестве единицы и поэтому будет более эффективным.

Его маловероятное резюме само по себе полезно, поскольку оно не дает данных выше того факта, что это было сигнализировано. Если вы представляете себе использование cv - например, связанный с потоком связанный список с производителями и потребителями, у вас есть переменные, представляющие {list, cv, lock}. В этом случае вы берете блокировку, мутируете список, освобождаете блокировку, а затем сигнализируете cv. В вашей потребительской цепочке вам, скорее всего, понадобится блокировать один раз, чтобы сигнализировать о том, чтобы действовать в списке, поэтому наличие блокировки, полученной после того, как вы проснетесь с сообщенным сигналом, является хорошей вещью.

Посмотрите на что-то вроде событий на windows (:: CreateEvent), которые являются cv без неявной блокировки, и много времени, когда у них будет связанная с ними блокировка, но просто не встроены в фактическое использование.

Хотя это не первоначальная причина, в которой была создана переменная условия в pthreads (они использовали блокировку для защиты самого cv, который больше не нужен в С++), причина и полезность блокировок cv мигрировала в то, что в этом ответе.