Pthread_cond_wait vs semaphore

What are the pros and cons of using pthread_cond_wait or using a semaphore? I am waiting for the state change as follows:

 pthread_mutex_lock(&cam->video_lock); while(cam->status == WAIT_DISPLAY) { pthread_cond_wait(&cam->video_cond, &cam->video_lock); } pthread_mutex_unlock(&cam->video_lock); 

Using a properly initialized semaphore, I think I could do it like this:

 while(cam->status == WAIT_DISPLAY) { sem_wait(&some_semaphore); } 

What are the advantages and disadvantages of each method?

+41
c multithreading semaphore
Sep 16 '08 at 9:40
source share
4 answers

The semaphore fits the producer-consumer model purely, although it has other uses. Your program logic is responsible for ensuring that the correct number of messages is made for the number of expectations. If you send a semaphore and no one is waiting for it, then when they wait, they will continue immediately. If your problem is such that it can be explained in terms of the meaning of the semaphore, then it is easy to solve it with a semaphore.

In some respects, the state variable is a little more forgiving. You can, for example, use cond_broadcast to wake up all the waiters, without the producer knowing how many there are. And if you are cond_signal condvar, no one is waiting on it, then nothing happens. It’s good if you don’t know if the listener will be interested. In addition, the listener should always check the state with the mutex in front of the wait - if they do not, then they can skip the signal and not wake up until the next (which will never happen).

So, the condition variable is suitable for notifying interested parties that the state has changed: you acquire a mutex, change state, signal (or broadcast) condvar and release the mutex. If this describes your problem, you are in condvar territory. If different listeners are interested in different conditions, you can simply broadcast, and each of them, in turn, will wake up, find out if they found the condition that they want, and if you do not wait again.

It is very rude to actually try to use the mutex and semaphore in this way. The problem arises when you want to accept a mutex, check the status, and then wait for the semaphore for changes. If you cannot atomize a mutex and wait on a semaphore (which you cannot in pthreads), you end up expecting a semaphore by holding the mutex. This blocks the mutex, which means that others cannot accept it to make the changes you care about. Thus, you will be tempted to add another mutex in a way that depends on your specific requirements. And maybe another semaphore. The result is usually the wrong code with harmful race conditions.

Variable conditions come out of this problem because calling cond_wait automatically releases the mutex, freeing it up for others to use. The mutex is restored before cond_wait returns.

IIRC can implement some kind of condvar using only semaphores, but if the mutex that you implement to go with condvar requires a trylock, then this is a serious thug, and there are no timer expectations. Not recommended. Therefore, do not assume that everything you can do with condvar can be done with semaphores. Plus, of course, mutexes can have nice behavior that doesn't have semaphores, primarily avoiding priorities.

+58
Sep 20 '08 at 18:21
source share

Conditional words allow you to do some things that do not have semaphores.

For example, suppose you have a code that requires a mutex called m . However, it needs to wait until some other thread completes its task, so it waits for a semaphore called s . Now any thread that needs m is blocked from starting, although the thread that has m is waiting on s . These situations can be resolved using conditional expressions. When you wait at a conditional level, the mutex that is currently located is freed, so other threads can receive the mutex. So, back to our example and suppose that conditional c used instead of s . Now our thread acquires m , and then conditionally waits on c . This frees m to continue working with other threads. When c becomes available, m loads again, and our original thread can continue to have fun along its way.

Conditional variables also allow all threads waiting for a conditional variable to go through pthread_cond_broadcast . In addition, it also allows you to fulfill the expected wait time so that you do not wait forever.

Of course, sometimes you don’t need conditional variables, so one or the other may be better depending on your requirements.

+19
Sep 16 '08 at 11:15
source share

The second fragment is bright, do not do this.

Other answers have a good discussion of relative merits; I will simply add that pthread_cond_broadcast is a clear advantage of condition variables.

Also, I'm just more used to using variables for this, since they are used in Java, even because they help you avoid racing when checking for common flags.

In fact, in the second fragment you do not have a lock protecting the reading of cam-> status, therefore it is available through the data race. Most platforms will allow you to get away from this in this particular example, but it has undefined semantics, POSIX, and the memory model of the following C / C ++ standards.

In fact, a real race condition is possible if another thread distributes the new cam structure and overwrites the cam; the waiting thread can see the "cam" pointer update without seeing the cam-> status initialization. Indeed, the second fragment poses problems, in this case and in general.

http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/

+4
Jan 12 '09 at 9:11
source share

In the second fragment, you get a lot of locks, never releasing it.

In general, the state you are in can be fully expressed by a semaphore, then you can use just that. The blocking structure is smaller and less atomic operations are required for verification / installation / release.

Otherwise, if the state is complex, and different parts of the code are waiting under the different conditions of the same variable (for example, here you want x <10, there you want y> x), use cond_wait.

0
Sep 16 '08 at 10:10
source share



All Articles