Consider a simple (global in my case) variable:
int i;
Somewhere this variable is accessed
pthread_mutex_lock(i_mutex); if(i == other value) { do_something(); } pthread_mutex_unlock(i_mutex);
Another thread updates i
while it holds i_mutex
. Could the compiler cache the value of i
so I don't get the recent value ? Must i
be volatile ?
Yes, it is a blocking call and will block until it gets the lock.
Mutexes are used to protect shared resources. If the mutex is already locked by another thread, the thread waits for the mutex to become available. The thread that has locked a mutex becomes its current owner and remains the owner until the same thread has unlocked it.
pthread_mutex_lock() is not a cancellation point, although it may block indefinitely; making pthread_mutex_lock() a cancellation point would make writing correct cancellation handlers difficult, if not impossible.
The pthread_cond_wait() function atomically unlocks mutex and performs the wait for the condition. In this case, atomically means with respect to the mutex and the condition variable and another threads access to those objects through the pthread condition variable interfaces.
pthread locks implement memory barriers that will ensure that cache effects are made visible to other threads. You don't need volatile to properly deal with the shared variable i
if the accesses to the shared variable are protected by pthread mutexes.
from http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11:
The following functions synchronize memory with respect to other threads:
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()
A compiler should not cache such a global value across a function call.
But I think your question is ill-posed. First, POSIX mutex only work when you stick to their semantics. So you have to apply some discipline in your code to only access global variables (i
in that case) whence your mutex is hold.
Second, please don't think that volatile
declarations would prevent you from any damage that such a non-respect of the access rules would cause. Concurrent read and write into memory is a subtle subject.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With