Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

c - pthread_cond_wait versus semaphore

What are the pros / cons of using pthread_cond_wait or using a semaphore ? I am waiting for a state change like this :

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 initialised semaphore, I think I could do it like this :

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

What are the pros and cons of each method ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A semaphore is suited cleanly to a producer-consumer model, although it has other uses. Your program logic is responsible for ensuring that the right number of posts are made for the number of waits. If you post a semaphore and nobody is waiting on it yet, then when they do wait they continue immediately. If your problem is such that it can be explained in terms of the count value of a semaphore, then it should be easy to solve with a semaphore.

A condition variable is a bit more forgiving in some respects. You can for example use cond_broadcast to wake up all waiters, without the producer knowing how many there are. And if you cond_signal a condvar with nobody waiting on it then nothing happens. This is good if you don't know whether there's going to be a listener interested. It is also why the listener should always check the state with the mutex held before waiting - if they don't then they can miss a signal and not wake up until the next one (which could be never).

So a condition variable is suitable for notifying interested parties that state has changed: you acquire the mutex, change the state, signal (or broadcast) the condvar and release the mutex. If this describes your problem you're in condvar territory. If different listeners are interested in different states you can just broadcast and they'll each in turn wake up, figure out whether they've found the state they want, and if not wait again.

It's very gnarly indeed to attempt this sort of thing with a mutex and a semaphore. The problem comes when you want to take the mutex, check some state, then wait on the semaphore for changes. Unless you can atomically release the mutex and wait on the semaphore (which in pthreads you can't), you end up waiting on the semaphore while holding the mutex. This blocks the mutex, meaning that others can't take it to make the change you care about. So you will be tempted to add another mutex in a way which depends on your specific requirements. And maybe another semaphore. The result is generally incorrect code with harmful race conditions.

Condition variables escape this problem, because calling cond_wait automatically releases the mutex, freeing it for use by others. The mutex is regained before cond_wait returns.

IIRC it is possible to implement a kind of condvar using only semaphores, but if the mutex you're implementing to go with the condvar is required to have trylock, then it's a serious head-scratcher, and timed waits are out. Not recommended. So don't assume that anything you can do with a condvar can be done with semaphores. Plus of course mutexes can have nice behaviours that semaphores lack, principally priority-inversion avoidance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...