互斥鎖和條件變數使用例項

2021-08-01 11:57:20 字數 3120 閱讀 8918

條件變數簡介:

條件變數是執行緒中的

東西,就是等待某一條件的發生,和訊號一樣。 用法

條件變數使我們可以睡眠等待某種條件出現。

條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:乙個執行緒等待"條件變數的條件成立"而掛起;另乙個執行緒使"條件成立"(給出條件成立訊號)。為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。

條件變數型別為 pthread_cond_t。

條件變數與互斥量一起使用的時候,允許執行緒以無競爭的方式等待特定的條件發生。

條件本身是由互斥量保護的。執行緒在改變條件變數狀態前必須先鎖住互斥量。

另一種是動態分配的條件變數,則用pthread_cond_init函式進行初始化。

在釋放底層的記憶體空間之前,可以使用pthread_cond_destroy對條件變數進行去初始化。

條件變數在使用前必須初始化,一種是靜態初始化:pthread_cond_t cond = pthread_cond_initializer;

pthread_cond_t cond = pthread_cond_initializer;  

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

int pthread_cond_destroy(pthread_cond_t *cond);

int pthread_cond_signal(pthread_cond_t *cond);//喚醒等待該條件變數上的某個執行緒

int pthread_cond_broadcast(pthread_cond_t *cond);//喚醒等待該條件變數上的所有執行緒

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

消費者將g_count每次減去1,生產者將g_count每次加1;消費者會判斷g_count的大小,如果g_count==0那麼消費者執行緒要阻塞;但是它還會一直占有鎖,所以這樣就阻止了其它執行緒對g_count的操作;此時我們要用到條件變數;呼叫pthread_cond_wait(&g_cond, &g_mutex);讓互斥鎖g_mutex在這個g_cond條件上等待;

執行緒呼叫pthread_cond_wait這個函式之後,核心會做下面這些事:

1,拿到鎖的執行緒,把鎖暫時釋放;

2,執行緒休眠,進行等待;

3,執行緒等待通知,要醒來。(重新獲取鎖)

執行緒庫將上面三步做成了原子性操作;和linux核心繫結在一起;

在生產者執行緒中當對g_count++之後(也就是生產了產品),會呼叫pthread_cond_signal(&g_cond);向這個條件變數g_cond上傳送乙個訊號,表示條件滿足;

如果條件滿足,那麼剛才因為呼叫pthread_cond_wait而等待的消費者執行緒會醒來(重新獲取鎖,再次判斷條件是否滿足);如果g_count>0,然後在臨界區進行操作,最後解鎖,離開臨界區;

因為涉及到多個執行緒對全域性變數g_count進行操作,所以要用執行緒互斥鎖對g_count進行控制;所以首先定義互斥鎖mutex,然後呼叫pthread_mutex_lock(&mutex)進行上鎖,對g_count進行操作之後再呼叫pthread_mutex_unlock(&mutex)進行解鎖;

我們還希望對g_count的最大值進行控制,比如希望它的最大值是10;那麼當g_count等於10的時候,就要等待;

#include #include #include #include #include #include #define custom_count 2

#define produce_count 3

int nnum, nloop;

int g_count = 0;

pthread_mutex_t mutex = pthread_mutex_initializer;

pthread_cond_t cond = pthread_mutex_initializer;

void *consume(void *arg)

printf("consume is %lu, g_count is %d\n", pthread_self(), g_count);

g_count--;

pthread_mutex_unlock(&mutex);

sleep(1);

} pthread_exit(null);

}void *produce(void *arg)

//不需要解鎖再上鎖,大於10,會解鎖,會continue,不會執行下面語句

printf("start produce the product\n");

g_count++;

printf("produce is %lu, g_count is %d\n", pthread_self(), g_count);

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

sleep(1);

} pthread_exit(null);

}int main()

sleep(3);

//建立生產者執行緒

for (i = 0; i < produce_count; i++)

//等待消費者執行緒

for (i = 0; i < custom_count; i++)

//等待生產者執行緒

中間省略一部分

互斥鎖和條件變數

互斥瑣 定義 指代相互排斥,最基本的同步形式。用於保護臨界區,以保證任何時刻只有乙個執行緒或乙個程序在執行其中的 上鎖 pthread mutex lock 臨界區解鎖 pthread mutex unlock 條件變數 定義 用於等待訊號,同步的另一種手段。每乙個條件變數總有乙個互斥瑣與之關聯。等...

互斥鎖和條件變數

mutex體現的是一種競爭,我離開了,通知你進來。cond體現的是一種協作,我準備好了,通知你開始吧。互斥鎖乙個明顯的缺點是它只有兩種狀態 鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖的不足,它常和互斥鎖一起配合使用。使用時,條件變數被用來阻塞乙個執行緒,當...

互斥鎖和條件變數

條件變數 執行緒最大的特點就是資源的共享性,然而資源共享中的同步問題是多執行緒程式設計的難點。互斥鎖通過鎖機制來實現執行緒間的同步。使用互斥鎖前必須進行初始化操作。初始化有兩種方式 一種是靜態賦值法,將將巨集結構常量pthread mutex initializer賦給互斥鎖,操作語句如下 pthr...