9f8 Subj : Re: Memory visibility with Pthreads To : comp.programming.threads From : Kaz Kylheku Date : Fri Sep 09 2005 04:28 pm Christoph Bartoschek wrote (about a month ago, I know!!!): > There are two global variables and a shared mutex: > > int A = 0; > int B = 0; > > Thread 1 executes the following code: > > A = 10; > pthread_mutex_lock(mutex); > B = 10; > pthread_mutex_unlock(mutex); > > Thread 2 executes another codesequence: > > pthread_mutex_lock(mutex); > if (B == 10) { > printf("The value of A is %d\n", A); > } else { > printf("B is not 10\n"); > } > pthread_mutex_unlock(mutex); > > One question is, whether it is legal to use the variable A in thread 2? The code is correct assuming that B had some value other than 10 to begin with, so we are not racing ahead and accessing A while it is being assigned just because B is accidentally equal to 10! Otherwise, everything is causally ordered. The code cannot behave as if the assignment to A happened after the assignment to B. All kinds of common program designs would fail miserably if that didn't work. Consider what would happen if A is a member of a structure pointed at by B. It's the same thing: // allocate and construct object OBJ OBJ->AMEMB = 10; lock(); BPTR = OBJ; unlock(); Then in the other thread: lock(); if (BPTR != NULL) printf("value of BPTR->AMEMB == %d\n", BPTR->AMEMB); unlock(); It's perfectly valid to prepare dependent data outside of a mutex and then inside the mutex, make that dependant data available in some indirect way. It's done all the time, just like in the above pattern. A thread constructs an object, locks a mutex, and gives that object to other threads by stashing it in a shared container, global pointer or whatever! The other threads lock the mutex, and fetch the object from that container or global pointer, and can use that pointer to access all of the properties of that object. The mutex must provide all of the memory visibility ordering that makes this work, otherwise we are screwed in 90% of our programs. Q.E.D. :) This is exactly the same as your A and B, since the access to A is dependent on B being set up to 10. B being 10 is the accessing condition that makes A available to the other thread, and A was set up before B was set to 10 inside the mutex. The functions don't care whether you are using a pointer or what; the mutex doesn't care about the exact details of your data. . 0