Subj : Re: Question : usage of conditional variables. To : comp.programming.threads From : David Butenhof Date : Thu Jun 09 2005 01:29 pm Jamie wrote: > Thanks David! > > Yeh, I had wrong understanding with condition variables, still > complicated. > Aftter I put the predicate (ready : TRUE/FALSE), my program runs well. > > But, what is this predicate for? A site said that "pthread_cond_wait() > is recommended to be used in a loop testing the predicate associated > with it. This will take care of any spurious wakeups that may occur." Why do you want to WAIT? There must be a reason. Maybe you want to remove a request from a work queue, and there's nothing on the queue. Maybe you want to add a request, and the queue is full. A "condition" of your shared data, like "queue full", "queue empty" is called a predicate. You can only examine or change predicates while you hold a lock (a mutex in this case) protecting the shared data. When you determine that the predicate isn't in the state you want, you need to WAIT for it; and you need to wait in a way that will allow some other thread to CHANGE the predicate in a way that allows you to resume. For example, to add a request to your empty queue, or to remove a request from your full queue. You wait using pthread_cond_wait (or pthread_cond_timedwait if there's something else you need to do should no other thread get around to doing the work within a known period of time). The semantics of these functions ensure that your thread will be "registered as waiting" before any other thread can acquire the mutex, change the predicate, and try to awaken a waiter. (Otherwise this might happen before you wait, and you wouldn't be awakened.) Since you're waiting for a predicate condition, you're going to need access to the shared data again after the wait (or else you wouldn't have bothered), so pthread_cond_[timed]wait returns with the mutex locked again. However, there's still a chance (due to all sorts of factors including the general unpredictability of multiprocessor scheduling and normal operation of your program) that the predicate really isn't true (or isn't true any more) by the time the thread is able to resume. Therefore, you should always RETEST the predicate; which is why we say that you should call pthread_cond_[timed]wait in a predicate test loop. > My program runs well for a while without predicate(not using a loop), > but it stops and wait a signal forever at some point.. After adding a > predicate and checking it before calling pthread_cond_wait(), it runs > well. But I can't understand why sometimes it works well without > predicate and sometimes not.. What does the spurious wakeups really > mean? Spurious wakeups mean that some factor in the system (your application, the thread scheduler, whatever) has caused your thread to wake up and find that the predicate condition isn't true. It's no big deal; most often it's a GOOD thing, because it means that some thread was able to process the condition sooner than this thread could have. (But it may also mean that some thread signalled or broadcast the condition variable when the predicate really wasn't true, or that it broadcast and some other thread woke up first, or even noticed the predicate before it waited.) If you're really trying to sleep "just to sleep", without any particular intent (you're not waiting "for something"), then you probably should be using some mechanism other than condition variables. They're designed specifically to allow you to reliably wait for some defined change in a predicate that's protected by a mutex; and only for that. If you have some vastly different purpose, a semaphore, or even a simple sleep() call, might be more appropriate. (But of course we can't give any specific advice unless we know what you need, and why.) -- Dave Butenhof, David.Butenhof@hp.com HP Utility Pricing software, POSIX thread consultant Manageability Solutions Lab (MSL), Hewlett-Packard Company 110 Spit Brook Road, ZK2/3-Q18, Nashua, NH 03062 .