views:

293

answers:

1

With a pthread_cond_t we have to associate a mutex, When signalling the condition I've seen code such as

pthread_mutex_lock(&mutex);

//code that makes condition true

pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);

and

pthread_mutex_lock(&mutex);

//code that makes condition true

pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond);

Which one is the proper way ? (Does it matter ?)

+6  A: 

Depends what the sinks are doing (and any other sources).

In your second code sample, it's possible that in between unlock and broadcast, a bunch of other threads will come along and do some combination of things which makes the condition false again. You'll then be broadcasting pointlessly. And you won't necessarily have the same set of waiters as were there when you changed the condition, which may or may not affect your design.

A decent sink shouldn't care if it gets woken up and the condition is false, especially if you're using broadcast. As long as every change of condition to "true" is eventually followed by a broadcast, I'm pretty sure that with appropriately-written sinks, you can broadcast a condition variable willy-nilly with or without the lock.

So I don't think it really matters, but personally I'd broadcast with the lock held, if only to avoid having to worry about it. "Atomic change-and-signal" might simplify the state diagram on your whiteboard compared with "change ... some time later, signal".

Both are proper (unlike waiting without the mutex, which isn't allowed), but I don't think it would be too difficult to come up with uses which can go wrong in the second case, that wouldn't go wrong in the first. They'd probably have to involve some waiters doing slightly unusual things, though.

The spec rather cryptically says "if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal()."

http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

Steve Jessop