[clug] pthread coroutines

Ian McCulloch ianmcc at lorentz.leidenuniv.nl
Mon Feb 9 12:32:34 GMT 2004


On Wed, 2 Jul 2003, Andrew Over wrote:

> On Wed, Jul 02, 2003 at 06:04:49PM +1000, Simon Burton wrote:
> 
> > How to use mutexes so that effectively only one out of two threads
> > is running at a time? Like co-routines. Each thread blocks on a 
> > pthread_mutex_lock() while the other is running. I'm sure it will come to me
> > eventually. Or is there Another Way? 
> 
> Not quite sure why you want this, but...
> 
> ... use a mutex and a condition variable?

In this particular case, the condition variable is not needed, each thread 
can just grab the mutex and keep it until it is ready to pass control to 
the other thread.

> 
> When you're done doing your work, just go:
> 
>   pthread_mutex_lock(&mtx);
>   pthread_cond_signal(&cvar);        // Wake up the other thread
>   pthread_cond_wait(&cvar, &mtx);    // Now sleep ourselves
>   pthread_mutex_unlock(&mtx);

Maybe overkil, but fine - except that condition variables 
should always be used in conjunction with a test, not replacing it:

Sleep code:

pthread_mutex_lock(&mtx);
while (NextThread != MyThreadID) // this line is a critical section
{
   pthread_cond_wait(&cvar, &mtx);
}
pthread_mutex_unlock(&mtx);

Wakeup code:

pthread_mutex_lock(&mtx);
NextThread = OtherThreadID;  // another critical section
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mtx);

The reason for this is (1) good style, and (2) that POSIX allows for 
pthread_cond_wait() to unblock even if no thread has actually signalled 
the condition variable, so it is needed for correctness (not sure whether 
linux has this semantics though).

This also has fewer initialization problems (if thread 1 signals the 
condition before thread 2 hits the pthread_cond_wait() then the signal is 
lost - that doesn't matter if you test before sleeping).

> 
> The mutex is only necessary to avoid a race condition (someone calling
> wait just as someone else calls signal).  Basically, you initialise
> things so that one process waits on the condition variable.  When a
> thread has finished doing its thing, it signals to wake up the other
> thread, then goes to sleep itself, releasing the mutex and allowing the
> other thread to run (since pthread_cond_wait reacquires the mutex before
> returning).
> 
> I think you could also achieve the same result using two semaphores (one
> for each thread).  When done, each thread posts the other, then waits
> on its own. 

That would work too.

Cheers,
Ian



More information about the linux mailing list