Thursday, April 11, 2013

Thread synchronization

Q: How to use pthread_cond_wait();
Ans :  
       int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 
It's used to block on a condition variable.Its called with mutex locked by the
calling thread. It atomically release mutex and cause the calling thread to block on the condition variable cond;
atomically here means "atomically with respect to access by another thread to the mutex and then the condition 
variable".Upon successful return,the mutex has been locked and is owned by the calling thread.
Spurious wakeups from the pthread_cond_wait() or pthread_cond_timedwait()functions may occur.Since the return
from pthread_cond_wait() or pthread_cond_timedwait() does not imply anything about the value of this predicate,the
predicate should be re-evaluated upon such return. That's why  conditional wait is put in while Loop to check DATA instead
of if condition. This make sures that threads comes out only id DATA has met condition,
else go in wait again.......  
 
Usage:
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 int avail = 0; 
 
Worker  Thread: 
 pthread_mutex_lock(&mutex);
 avail++; /* Let consumer know another unit is available */
 pthread_mutex_unlock(&mutex);
 if(avail == THRESHOLD)
     pthread_cond_signal(&cond); /* Wake sleeping consumer */
 
Reader Thread:
pthread_mutex_lock(&mutex);
while (avail != THRESHOLD)/* Check that shared variable is not in state we want */
 pthread_cond_wait(&cond, &mutex);
}
/* Now shared variable is in desired state; do some work */
 pthread_mutex_unlock(&mutex);
-------------------------------------------------------------------------------------
 pthread_cond_wait internally does three things :
 1) unlock the mutex specified by mutex;
 2) block the calling thread until another thread signals the condition variable cond; and
 3) relock mutex.
-------------------------------------------------------------------------------------
We can’t make any assumptions about the state of the predicate upon return from pthread_cond_wait(), 
for the following reasons:
1   Other threads may be woken up first: Perhaps several threads were waiting to acquire the mutex associated with
  the condition variable. Even if the thread that signaled the mutex set the predicate to the desired state, it is still 
  possible that another thread might acquire the mutex first and change the state of the associated shared variable(s),
  and thus the state of the predicate may be changed.

2   Designing for “loose” predicates may be simpler. Sometimes, it is easier to design applications based on condition 
  variables that indicate possibility rather than certainty. In other words, signaling a condition variable would mean
  "there may be something” for the signaled thread to do, rather than “there is something” to do. Using this approach,
  the condition variable can be signaled based on approximations of the predicate’s state, and the signaled thread 
  can ascertain if there really is something to do by rechecking the predicate.

3   Spurious wake-ups can occur. On some implementations, a thread waiting on a condition variable may be woken
  up even though no other thread actually signaled the condition variable. Such spurious wake-ups are a (rare) consequence
  of the techniques required for efficient implementation on some multiprocessor systems, and are explicitly permitted by SUSv3.
TO  Wake up ALL threads waiting use 
pthread_cond_broadcast() this will wake all threads.

No comments: