Matthew Iselin
Matthew Iselin

Reputation: 10670

POSIX Threads: Condition Variables - what's the point?

I've been working with pthreads a fair bit recently and there's one little thing I still don't quite get. I know that condition variables are designed to wait for a specific condition to come true (or be 'signalled'). My question is, how does this differ at all from normal mutexes?

From what I understand, aren't condition variables just a mutex with additional logic to unlock another mutex (and lock it again) when the condition becomes true?

Psuedocode example:

mutex mymutex;
condvar mycond;
int somevalue = 0;

onethread()
{
    lock(mymutex);

    while(somevalue == 0)
        cond_wait(mycond, mymutex);

    if(somevalue == 0xdeadbeef)
        some_func()

    unlock(mymutex);
}

otherthread()
{
    lock(mymutex);

    somevalue = 0xdeadbeef;

    cond_signal(mycond);

    unlock(mymutex);
}

So cond_wait in this example unlocks mymutex, and then waits for mycond to be signalled.

If this is so, aren't condition variables just mutexes with extra magic? Or do I have a misunderstanding of the fundamental basics of mutexes and condition variables?

Upvotes: 4

Views: 8801

Answers (3)

1800 INFORMATION
1800 INFORMATION

Reputation: 135393

The two structures are quite different. A mutex is meant to provide serialised access to a resource of some kind. A condition variable is meant to allow one thread to notify some other thread that some event has occurred.

Upvotes: 16

leiz
leiz

Reputation: 4052

The simple answer is that you might want to wake more than one thread from the condition variables, but mutex allows only one thread execute the guarded block.

Upvotes: 5

Logan Capaldo
Logan Capaldo

Reputation: 40346

They aren't exactly mutexes with extra magic, although in some abstractions (monitor as used in java and C#) the condition variable and the mutex are combined into a single unit. The purpose of condition variables is to avoid busing waiting/polling and to hint to the run time which thread(s) should be scheduled "next". Consider how you would write this example without condition variables.

while(1) {
  lock(mymutex)
  if( somevalue != 0)
     break;
  unlock(mymutex);
}

if( somevalue == 0xdeadbeef )
  myfunc();

You'll be sitting in a tight loop in this thread, burning up a lot of cpu, and making for a lot of lock contention. If locking/unlocking a mutex is cheap enough, you may be in a situation where otherthread never even has a chance to obtain the lock (although real world mutexes generally distinguish between the owning thread and having the lock, as well as having notions of fairness so this is unlikely to happen in reality).

You could reduce the busy waiting by sticking a sleep in,

while(1) {
  lock(mymutex)
  if( somevalue != 0)
     break;
  unlock(mymutex);
  sleep(1); // let some other thread do work
}

but how long is a good time to sleep for? You'll basically just be guessing. The run time also can't tell why you are sleeping, or what you are waiting on. A condition variable lets the run time be at least somewhat aware of what threads are interested in the same event currently.

Upvotes: 14

Related Questions