Just so you know what was going on, a "tight loop" consumes your thread's CPU allotment just like any other code your thread executes. The only difference is that it accomplishes nothing. Well I guess making the core warm is something... You probably never want to do that unless you care about the cost of the context switch and you know for sure that the wait time is going to be much shorter than your thread's timeslice, which is about 1ms. I don't know if sleep is as bad as yield (AFAIK yield sets your thread the the back of the list of threads to activate at your priority level) , but both at least incur the penalty of a context switch. There is a cost to context switching. A context switch is what happens when your thread's timeslice ends. It can either end because you ended it with a yield or a sleep, or if the kernel ended it by pre-empting you. Read about SMP and spinlocks to understand more about context switches and cases when a tight loop is applicable.
Also, when you sleep, you don't exactly know when you will wake up again. so one reason you might not want to sleep is you need to get something done fast. You could wait a couple ms before being rescheduled.
Everyone else gave you the pthread_cond_wait solution, which requires locking via mutexes and looks straightforward and simple. The performance might be adequate for your needs, but is relatively slow compared to a solution using signals (sigwait and pthread_kill). The complexity will sneak up on you.
Not discussed here is why you lock a mutex before testing if you need to wait on the condition. The reason is that code like this has a flaw:
while (x <= y) {
pthread_cond_wait(&cond, &mut);
}
Your thread could test ( X<=Y ), see that it has to wait, but be pre-epted before it attaches itself to the condition value. Some other thread, who just modified x or y, signals the condition in that timeslice before the first thread attaches to the condition. In this way, the condition signal is lost. So what ends up happening is everywhere you modify the variables afecting the signal, you have to add locks.
pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mut);
This may mean you add these mutex locks in many different places and your code gets more complex and slower because of that. The possibility of a hung thread waiting for a condition is always there. The loop, test, sleep solution has none of those issues. So if the wait time is known to be short, using sleep in a loop is probably a fine solution. Especially if you can sleep for a second or more between tests. If you can, then don't bother with mutexes and conditions. If the sleep time is short, like 1ms and the wait time is long, like minutes or hours, then you will end up wasting some resources by continually waking up and going back to sleep. You have to judge.
Also be aware that sometimes the kernel will try to wake the waiter thread immediately and other times there will be a delay. If the thread wakes too soon, it will wake while the mutex is locked and immediately go back to sleep until the mutex unlocks. If that becomes a problem, signal the condition this way:
pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) {
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cond);
} else
pthread_mutex_unlock(&mut);
Thanks go to user576875, who's code samples I copied.