Does guarding a variable with a pthread mutex guarantee it's also not cached?

Solution 1:

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()

Solution 2:

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.

Solution 3:

The simple answers to your question are:
- No, i will be the most recent value.
- No, i does not have to be volatile.

The i_mutex protects your access to i...as long as your lock the mutex every time you read and write it. Simple as that.

In other words, you don't have to worry about caching or volatile.

Enjoy, Randy