1 簡介
當多個線程之間因為存在某種依賴關系,導致只有當某個條件存在時,才可以執行某個線程,此時條件變量(pthread_cond_t)可以派上用場。比如:
例1: 當系統不忙(這是一個條件)時,執行掃描文件狀態的線程。
例2: 多個線程組成線程池,只有當任務隊列中存在任務時,才用其中一個線程去執行這個任務。為避免驚群(thrundering herd),可以采用條件變量同步線程池中的線程。
2 用法
條件變量(pthread_cond_t)必須與鎖(pthread_mutex_t)一起使用。
條件變量的API:
1) pthread_cond_init
2) pthread_cond_signal / pthread_cond_broadcast
3) pthread_cond_wait / pthread_cond_timedwait
4) pthread_cond_destroy
線程A:
include <stdio.h>
include <sys/time.h>
include <unistd.h>
include <pthread.h>
include <errno.h>
...
void A_thread_run(void *arg)
{
...
pthread_mutex_lock (& lock);
// 條件滿足, 發出通知
pthread_cond_signal (& cond);
pthread_mutex_unlock (& lock);
...
}
線程B:
void B_thread_run(void *arg)
{
for ( ; ; ) {
pthread_mutex_lock (&lock);
/* pthread_cond_wait 原子調用: 等待條件變量, 解除鎖, 然後阻塞
* 當 pthread_cond_wait 返回,則條件變量有信號,同時上鎖
*
* 等待條件有兩種方式:條件等待pthread_cond_wait()和計時等待pthread_cond_timedwait(),
* 其中計時等待方式如果在給定時刻前條件沒有滿足,則返回ETIMEOUT
* 無論哪種等待方式,都必須和一個互斥鎖配合,以防止多個線程同時請求pthread_cond_wait()
* (或pthread_cond_timedwait(),下同)的競爭條件(Race Condition)。
* mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應鎖(PTHREAD_MUTEX_ADAPTIVE_NP),
* 且在調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,
* mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。
* 在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。
* 激發條件有兩種形式,pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個;
* 而pthread_cond_broadcast()則激活所有等待線程(驚群)。
*/
pthread_cond_wait (&cond, &lock);
if (shutdown) {
break;
}
/* Unlock */
pthread_mutex_unlock (&lock);
/* do your task here */
}
pthread_mutex_unlock (&lock);
pthread_exit (0);
}
線程B調用pthread_cond_wait,從而阻塞在此句,等待有信號通知。pthread_cond_wait內部存在原子調用:解除鎖和等待條件變量有信號。當pthread_cond_wait函數返回,表明得到了信號通知,同時上鎖。
線程A用pthread_cond_signal通知調用了pthread_cond_wait的線程B。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/105144p2.htm