linux中的條件變量


1 條件變量認識

(1)大家可能知道互斥量是線程程序中必須的工具了,但是也不能是萬能的,就比如某個線程正在等待共享數據某個條件的發生,這個時候會發生什么呢。它就可能重復的嘗試對互斥對象鎖定和解鎖來檢查共享數據結構。

(2)線程在等待滿足某些條件的時候使線程進入睡眠狀態,一旦條件滿足了就喚醒並等待滿足特定條件而睡眠的線程。

(3)條件變量一般都允許線程阻塞和等待另一個線程發送信號的方法來彌補互斥鎖的不足。

2 函數介紹

(1) 靜態方式使用 pthread_cond_t cond=PTHREAD_COND_INITIALIZER

動態方式 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr)

-------->當cond_attr為null的時候使用默認的屬性。

(2)注銷一個條件變量

int pthread_cond_destroy(pthread_cond_t *cond)只有沒有線程在這個條件變量的時候才能注銷這個條件變量。

(3)等待有兩種方式,條件等待和時間等待。無論哪種等待都必須和一個互斥鎖配合來防止多個線程同時請求pthread_cond_wait()這個競爭條件。

(4)激發 兩種方式,pthread_cond_signal()激活一個等待該條件的線程。pthread_cond_broadcast()激活所有等待線程。

3 例子

(1)第一個例子

 1 #include <iostream>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 using namespace std;
 5 pthread_cond_t qready = PTHREAD_COND_INITIALIZER;    /*初始構造條件變量*/
 6 pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;    /*初始構造鎖*/
 7 int x = 10;
 8 int y = 20;
 9 void *func1(void *arg){
10     cout<<"func1 開始"<<endl;
11     pthread_mutex_lock(&qlock);
12     while(x<y)
13     {
14         pthread_cond_wait(&qready,&qlock);
15     }
16     pthread_mutex_unlock(&qlock);
17     sleep(3);
18     cout<<"func1 結束"<<endl;
19 }
20 void *func2(void *arg){
21     cout<<"func2 開始"<<endl;
22     pthread_mutex_lock(&qlock);
23     //修改xy
24     x = 20;
25     y = 10;
26     cout<<"has change x and y"<<endl;
27     pthread_mutex_unlock(&qlock);
28     if(x > y){
29         pthread_cond_signal(&qready);//發送信號 使線程1不阻塞
30     }
31     cout<<"func2 結束"<<endl;
32 }
33 int main(int argc,char **argv){
34     pthread_t tid1,tid2;
35     int iRet;
36     iRet = pthread_create(&tid1,NULL,func1,NULL);
37     if(iRet){
38         cout<<"pthread 1 create error"<<endl;
39         return iRet;
40     }
41     sleep(2);
42     iRet = pthread_create(&tid2,NULL,func2,NULL);
43     if(iRet){
44         cout<<"pthread 2 create error"<<endl;
45         return iRet;
46     }
47     sleep(5);    
48     return 0;    
49 }
View Code

(2)第二個例子

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 #include <pthread.h>
 6 #include <errno.h>
 7 #include <iostream>
 8 #include <pthread.h>
 9 using namespace std;
10 
11 /*提示出租車到達的條件變量*/
12 pthread_cond_t taxiCond = PTHREAD_COND_INITIALIZER; 
13 /*同步鎖*/
14 pthread_mutex_t taxiMutex = PTHREAD_MUTEX_INITIALIZER;   
15 
16 int travelerCound=0;
17 //旅客到來的時候 數量加上1
18 void * traveler_arrive(void * name){
19     cout<<"Traveler: "<<(char *)name<<" needs a taxi now!"<<endl;
20     pthread_mutex_lock(&taxiMutex);
21     travelerCound++;
22     pthread_cond_wait(&taxiCond,&taxiMutex);
23     pthread_mutex_unlock(&taxiMutex);
24     cout<<"Traveler: "<<(char *)name<<" now got a taxi!"<<endl;
25     pthread_exit((void*)0);
26 }
27 
28 void * taxi_arrive(void * name){
29     cout<<"Taxi: "<<(char *)name<<" arrives."<<endl;
30     //保證先來的檢測是否有新的顧客到達
31     while(1){
32         pthread_mutex_lock(&taxiMutex);
33         //大於則通知
34         if(travelerCound>0){
35             pthread_cond_signal(&taxiCond);
36             pthread_mutex_unlock(&taxiMutex);    
37             break;            
38         }
39         pthread_mutex_unlock(&taxiMutex);
40     }
41     pthread_exit((void*)0);
42 }
43 
44 int main(){
45     pthread_t tids[3];
46     int iRet = pthread_create(&tids[0],NULL,taxi_arrive,(void*)(" Jack "));
47     if(iRet){
48         printf("pthread_create error: iRet=%d\n",iRet);
49         return iRet;
50     }
51     printf("Time passing by.\n");
52     sleep(1);
53     iRet = pthread_create(&tids[1],NULL,traveler_arrive,(void*)(" Susan "));
54     if(iRet){
55         printf("pthread_create error: iRet=%d\n",iRet);
56         return iRet;
57     }
58     printf("Time passing by.\n");
59     sleep(1);    
60     iRet = pthread_create(&tids[2],NULL,taxi_arrive,(void*)(" Mike "));
61     if(iRet){
62         printf("pthread_create error: iRet=%d\n",iRet);
63         return iRet;
64     }    
65     printf("Time passing by.\n");
66     sleep(1);
67     
68     void *retval;    
69     for(int i=0;i<3;i++){
70         iRet=pthread_join(tids[i],&retval);
71         if (iRet){
72             printf("pthread_join error: iRet=%d\n",iRet);
73             return iRet;
74         }
75         printf("retval=%ld\n",(long)retval);    
76     }
77     return 0;    
78 }

好叻 加油!!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM