Переменные условия все еще нуждаются в мьютексе, если вы изменяете проверенное значение атомарно?
Вот типичный способ использования условной переменной:
// The reader(s)
lock(some_mutex);
if(protected_by_mutex_var != desired_value)
some_condition.wait(some_mutex);
unlock(some_mutex);
// The writer
lock(some_mutex);
protected_by_mutex_var = desired_value;
unlock(some_mutex);
some_condition.notify_all();
Но если protected_by_mutex_var установлен атомарно, скажем, инструкция сравнения и обмена, служит ли мьютекс какой-либо цели (кроме того, что pthreads и другие API требуют, чтобы вы передавали мьютекс)? Используется ли защищающее государство для выполнения условия? Если нет, то безопасно ли это делать?
// The writer
atomic_set(protected_by_mutex_var, desired_value);
some_condition.notify_all();
С писателем, никогда напрямую не взаимодействующим с мьютексом читателя? Обратите внимание, что имя 'protected_by_mutex_var' больше не подходит (больше не защищено мьютексом). Если да, то нужно ли, чтобы разные читатели использовали один и тот же мьютекс?
1 ответ
Представьте себе следующий сценарий:
| Thread 1 | Thread 2 |
| if(protected_by_mutex_var != desired_value) -> true | |
| | atomic_set(protected_by_mutex_var, desired_value); |
| | some_condition.notify_all(); |
| some_condition.wait(some_mutex); | |
В этой ситуации поток 1 ожидает уведомления, которое может никогда не прийти. Поскольку операторы, действующие на условии, не являются частью переменного набора чтения / атома, это представляет условие гонки.
Эффективное использование мьютекса делает эти действия неотделимыми (при условии, что все обращения к переменной ведут себя правильно и блокируют мьютекс).