Защищает ли переменная переменную mutex pthread, также она не кэшируется?
Рассмотрим простую (глобальную в моем случае) переменную:
int i;
Где-то доступна эта переменная
pthread_mutex_lock(i_mutex);
if(i == other value) {
do_something();
}
pthread_mutex_unlock(i_mutex);
Другой поток обновляет i
, пока он держит i_mutex
. Может ли компилятор кэшировать значение i
так
Я не получил последнее значение? Должен i
быть неустойчивым?
Ответы
Ответ 1
блокировки pthread реализуют барьеры памяти, которые гарантируют, что эффекты кеша становятся видимыми для других потоков. Вам не требуется волатильность для правильной работы с общей переменной i
, если доступ к общей переменной защищен мьютексами pthread.
из http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11:
Следующие функции синхронизируются памяти по отношению к другим потокам:
fork()
pthread_barrier_wait()
pthread_cond_broadcast()
pthread_cond_signal()
pthread_cond_timedwait()
pthread_cond_wait()
pthread_create()
pthread_join()
pthread_mutex_lock() // <====
pthread_mutex_timedlock()
pthread_mutex_trylock()
pthread_mutex_unlock() // <====
pthread_spin_lock()
pthread_spin_trylock()
pthread_spin_unlock()
pthread_rwlock_rdlock()
pthread_rwlock_timedrdlock()
pthread_rwlock_timedwrlock()
pthread_rwlock_tryrdlock()
pthread_rwlock_trywrlock()
pthread_rwlock_unlock()
pthread_rwlock_wrlock()
sem_post()
sem_timedwait()
sem_trywait()
sem_wait()
semctl()
semop()
wait()
waitpid()
Ответ 2
Компилятор не должен кэшировать такое глобальное значение во время вызова функции.
Но я думаю, что ваш вопрос неверен. Во-первых, Mutex POSIX работает только тогда, когда вы придерживаетесь их семантики. Поэтому вам нужно применить некоторую дисциплину в своем коде, чтобы получить доступ только к глобальным переменным (i
в этом случае), когда ваш мьютекс удерживается.
Во-вторых, пожалуйста, не думайте, что объявления volatile
помешали бы вам получить какой-либо ущерб, который может вызвать такое несоблюдение правил доступа. Одновременное чтение и запись в память - тонкий предмет.
Ответ 3
Простые ответы на ваш вопрос:
- Нет, я буду самым последним значением.
- Нет, я не должен быть неустойчивым.
i_mutex защищает ваш доступ к i... до тех пор, пока вы блокируете мьютекс каждый раз, когда вы его читаете и пишете. Просто как это.
Другими словами, вам не нужно беспокоиться о кешировании или неустойчивости.
Enjoy,
Ренди