加鎖與解鎖:
#include
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
All return: 0 if OK, error number on failure
對于讀者的數量會有限制,因此調用 pthread_rwlock_rdlock時需要檢查返回值。
在正確使用的情況下,不需要檢查pthread_rwlock_wrlock和pthread_rwlock_unlock的返回值。
條件加鎖:
#include
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
Both return: 0 if OK, error number on failure
10.什么是條件變量,它有什么作用?
條件變量是線程可用的另外一種同步機制。條件變量給多個線程提供了一個會合的場所。條件變量與互斥量一起使用時,允許線程以無競爭的方式等待特定條件的發生。條件本身是由互斥量保護的。線程在改變狀態前必須首先鎖住互斥量,其它線程在獲得互斥量之前不會覺察到這種變化。
11.如何使用條件變量?
條件變量的類型為pthread_cond_t ,其初始化與銷毀的方式與mutex類似,注意靜態變量可以通過指定常量PTHREAD_COND_INITIALIZER來進行初始化。
#include
int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
Both return: 0 if OK, error number on failure
使用pthread_cond_wait來等待條件變成真。
函數定義如下:
以下是代碼片段: #include int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout); Both return: 0 if OK, error number on failure |
注意,調用成功返回后,線程需要重新計算條件變量,因為其它線程可能已經改變了條件。
有兩個函數用于通知線程一個條件已經被滿足。pthread_cond_signal函數用來喚醒一個等待條件滿足的線程, pthread_cond_broadcast用來喚醒所有等待條件滿足的線程。
他們的定義為:
#include
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
Both return: 0 if OK, error number on failure
下面的這段代碼實現了類似于生產者消費者模型的程序,生產者通過enqueue_msg將消息放入隊列,并發送信號通知給消費者線程。消費者線程被喚醒然后處理消息。
#include
struct msg {
struct msg *m_next;
/* ... more stuff here ... */
};
struct msg *workq;
pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
void
process_msg(void)
{
struct msg *mp;
for (;;) {
pthread_mutex_lock(&qlock);
while (workq == NULL)
pthread_cond_wait(&qready, &qlock);
/*get msg from the queue*/
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/* now process the message mp */
}
}
void
enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
/*put msg in queue*/
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
在pthread_cond_signal發送消息之前并不需要占用鎖,因為一旦線程被喚醒后通過while發現沒有要處理的msg存在則會再次陷入睡眠。如果系統不能容忍這種競爭環境,則需要在unlock之前調用cond_signal,但是在多處理器機器上,這樣會導致多線程被喚醒然后立即進入阻塞(cond_signal喚醒線程,但由于我們仍占用著鎖,所以這些線程又會立即阻塞)。
原文轉自:http://blogread.cn/it/article/3344