Condition Variables(条件变量)用法指南
2010-12-30 12:01 zhenjing 阅读(3045) 评论(0) 编辑 收藏 举报int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
The pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a condition variable. They shall be called with mutex locked by the calling thread or undefined behavior results.
These functions atomically release mutex and cause the calling thread to block on the condition variable cond; Upon successful return, the mutex shall have been locked and shall be owned by the calling thread. (State change: lock=> unlock and block => unblock and lock)
NOTE(condition variable and mutex): The effect of using more than one mutex for concurrent pthread_cond_timedwait() or pthread_cond_wait() operations on the same condition variable is undefined.
Condition variable and thread cancellation
A condition wait (whether timed or not) is a cancellation point. When the cancelability enable state of a thread is set to PTHREAD_CANCEL_DEFERRED, a side effect of acting upon a cancellation request while in a condition wait is that the mutex is (in effect) re-acquired before calling the first cancellation cleanup handler.
NOTE: if the mutex should be unlocked after thread cancellation, then the first cancellation cleanup handler is used to unlock mutex generally!
A cancelled thread, which has been unblocked because it has been canceled while blocked in a call to pthread_cond_timedwait() or pthread_cond_wait(), shall not consume any condition signal.
Condition variable and signal
If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variableas if it was not interrupted, or it shall return zero due to spurious wakeup.
NOTE: It means that signal won’t block cond variable state!
Genaral Uasge
In general, whenever a condition wait returns, the thread has to re-evaluate the predicate associated with the condition waiting to determine whether it can safely proceed. A return from the wait does not imply that the associated predicate is either true or false. It is thus recommended that acondition wait be enclosed in the equivalent of a "while loop" thatchecks the predicate.
int pthread_cond_broadcast(pthread_cond_t*cond);
int pthread_cond_signal(pthread_cond_t *cond);
The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.
The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond
NOTE(waitup and mutex):The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().(The condition variable will be unblock but wait for mutex.)
The pthread_cond_broadcast() and pthread_cond_signal() functions shall have no effect if there are no threads currently blocked on cond.(It means multi calls is safe!)
Condition variable and signal handler
It is not safe to use the pthread_cond_signal() function in a signal handler that is invoked asynchronously.(It means pthread_cond_signal() shouldn’t be called in signal handler!)
Mutexes and condition variables are thus not suitable for releasing a waiting thread by signaling from code running in a signal handler.(Mutex and cond shouldn’t be used together with signal handler! IT IS NOT SAFE!)
Example:
typedef struct { pthread_mutex_t lock; pthread_cond_t rcond, wcond; int lock_count; /* < 0 .. Held by writer. */ /* > 0 .. Held by lock_count readers. */ /* = 0 .. Held by nobody. */ int waiting_writers; /* Count of waiting writers. */ } rwlock; void waiting_reader_cleanup(void *arg) { rwlock *l; l = (rwlock *) arg; pthread_mutex_unlock(&l->lock); } void lock_for_read(rwlock *l) { pthread_mutex_lock(&l->lock); pthread_cleanup_push(waiting_reader_cleanup, l); //unlock after cancel while ((l->lock_count < 0) && (l->waiting_writers != 0)) // while-loop pthread_cond_wait(&l->rcond, &l->lock); l->lock_count++; /* * Note the pthread_cleanup_pop executes * waiting_reader_cleanup. */ pthread_cleanup_pop(1); } void release_read_lock(rwlock *l) { pthread_mutex_lock(&l->lock); if (--l->lock_count == 0) pthread_cond_signal(&l->wcond); pthread_mutex_unlock(l); } void waiting_writer_cleanup(void *arg) { rwlock *l; l = (rwlock *) arg; if ((--l->waiting_writers == 0) && (l->lock_count >= 0)) { /* * This only happens if we have been canceled. */ pthread_cond_broadcast(&l->wcond); } pthread_mutex_unlock(&l->lock); } void lock_for_write(rwlock *l) { pthread_mutex_lock(&l->lock); l->waiting_writers++; pthread_cleanup_push(waiting_writer_cleanup, l); while (l->lock_count != 0) pthread_cond_wait(&l->wcond, &l->lock); l->lock_count = -1; /* * Note the pthread_cleanup_pop executes * waiting_writer_cleanup. */ pthread_cleanup_pop(1); } void release_write_lock(rwlock *l) { pthread_mutex_lock(&l->lock); l->lock_count = 0; if (l->waiting_writers == 0) pthread_cond_broadcast(&l->rcond) else pthread_cond_signal(&l->wcond); pthread_mutex_unlock(&l->lock); } /* * This function is called to initialize the read/write lock. */ void initialize_rwlock(rwlock *l) { pthread_mutex_init(&l->lock, pthread_mutexattr_default); pthread_cond_init(&l->wcond, pthread_condattr_default); pthread_cond_init(&l->rcond, pthread_condattr_default); l->lock_count = 0; l->waiting_writers = 0; } reader_thread() { lock_for_read(&lock); pthread_cleanup_push(release_read_lock, &lock); /* * Thread has read lock. */ pthread_cleanup_pop(1); } writer_thread() { lock_for_write(&lock); pthread_cleanup_push(release_write_lock, &lock); /* * Thread has write lock. */ pthread_cleanup_pop(1); }
---------------------------------------------------
兄弟的公司:立即购--手机购物,诚信网购
兄弟的公司:立即团
欢迎转载,请注明作者和出处
作者:zhenjing.chen
出处:http://www.cnblogs.com/zhenjing/
未注明转载的文章,版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。