條件變量用於線程之間的通信,和互斥鎖一起使用。條件變量用於及時通知等待的線程條件的變化,使線程不至於錯過變化。
考慮下面的情況,有AB兩個線程對index這個全局變量進行++,一個線程C用於判斷,index是不是3的倍數,如果是就輸出除以3的結果。
根據時間片輪轉的算法,線程應該是這樣執行的。
Index初值為1.
A B C (此時index=3,輸出)A B C(此時index=5,不輸出) A(此時index=6,c還在隊列的最后,錯過)BC 。。。。
我們能看出,C會每隔一段時間就錯個一個。
如圖:
因為三個線程的優先級一樣,不存在搶占,而且CPU是把時間片分給每個線程的,所以C的錯過是必然的。
所以引入了條件變量。
C線程調用pthread_cond_wait(cond,lock)函數來感知變化。
代碼:
#include <pthread.h> #include <semaphore.h> #include <unistd.h> #include <stdio.h> #include<fcntl.h> #include <pthread.h> #include <errno.h> int index = 1; pthread_mutex_t lock; pthread_cond_t cond; void fun1(void){ while(index<50){ pthread_mutex_lock(&lock); index++; printf("In fun1 : %d\n",index); pthread_cond_signal(&cond);//當有變化后,使用signal通知wait函數 pthread_mutex_unlock(&lock); usleep(0.1); } } void fun3(void){ while(index<50){ pthread_mutex_lock(&lock); index++; printf("In fun1 : %d\n",index); pthread_cond_signal(&cond); pthread_mutex_unlock(&lock); usleep(0.1); } } void fun2(void){ int i=0; while(i<70){ pthread_mutex_lock(&lock); while(index%3!=0){ pthread_cond_wait(&cond,&lock);//如果獲得了互斥鎖,但是條件不合適的話,wait會釋放鎖,不往下執行。當變化后,條件合適,將直接獲得鎖。 } //if(index%3==0) printf("%d\n",index/3); //else //printf("no\n"); i++; pthread_mutex_unlock(&lock); usleep(0.1); } } int main(){ pthread_mutex_init(&lock,NULL); pthread_cond_init(&cond,NULL); pthread_t tid1,tid2,tid3; pthread_create(&tid1,NULL,(void*)fun1,NULL); pthread_create(&tid2,NULL,(void*)fun2,NULL); pthread_create(&tid3,NULL,(void*)fun3,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_join(tid3,NULL); }