條件變量(condition variable)
創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的五華網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
線程間的同步與互斥技術(shù),主要以互斥鎖和條件變量為主,條件變量和互斥所的配合使用可以很好的處理對(duì)于條件等待的線程間的同步問(wèn)題。舉個(gè)例子:消費(fèi)者和生產(chǎn)者問(wèn)題。
消費(fèi)者與生產(chǎn)者最基本的關(guān)系是服務(wù)與被服務(wù)的關(guān)系,但是在線程同步與互斥中強(qiáng)調(diào)的是兩者訪問(wèn)資源的關(guān)系。首先生產(chǎn)與消費(fèi)的關(guān)系為:同步與互斥,生產(chǎn)與生產(chǎn)的關(guān)系為:互斥,消費(fèi)與消費(fèi)的關(guān)系為:互斥。所以維護(hù)這三種關(guān)系的有兩類人:生產(chǎn)者與消費(fèi)者。并且生產(chǎn)數(shù)據(jù)與消費(fèi)數(shù)據(jù)必須有場(chǎng)所。
所以將其簡(jiǎn)述為三種關(guān)系兩類人一個(gè)場(chǎng)所(當(dāng)然這里的場(chǎng)所并不是只能有一個(gè),可以是多樣的)。
介紹條件變量的幾個(gè)函數(shù):
1.定義一個(gè)條件變量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2.初始化條件變量(當(dāng)定義沒(méi)初始化時(shí))
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
3.銷毀條件變量
int pthread_cond_destroy(pthread_cond_t *cond)
舉一個(gè)單個(gè)消費(fèi)者與單個(gè)生產(chǎn)者問(wèn)題:
1 #include<stdio.h> 2 #include<pthread.h> 3 #include<assert.h> 4 #include<stdlib.h> 5 pthread_cond_t cond; 6 typedef int data_type; 7 pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER; 8 void push_node(data_type data); 9 int pop_node(); 10 void* producter(void* arg) 11 { 12 data_type i=0; 13 while(1) 14 { 15 pthread_mutex_lock(&lock); 16 i++; 17 push_node(i); 18 sleep(2); 19 pthread_mutex_unlock(&lock); 20 printf("product done......\n"); 21 sleep(2); 22 pthread_cond_signal(&cond); 23 sleep(2); 25 } 26 27 } 28 void *consumer(void* arg) 29 { 30 data_type res=-1; 31 while(1) 32 { 33 pthread_mutex_lock(&lock); 34 while(-1==pop_node(&res)) 35 { 36 pthread_cond_wait(&cond,&lock); 37 } 38 res=pop_node(&res); 39 printf("consumer data: %d\n",res); 40 sleep(2); 41 pthread_mutex_unlock(&lock); 44 pthread_cond_signal(&cond); 45 sleep(2); 46 47 } 48 49 } 50 51 typedef struct _node 52 { 53 data_type _data; 54 struct _node* _next; 55 }node, *node_p,**node_pp; 56 57 node_p head=NULL; 58 static node_p buy_node(data_type data) 59 { 60 node_p tmp=malloc(sizeof(node)); 61 if(tmp==NULL) 62 { 63 printf("malloc failed\n"); 64 65 } 66 tmp->_data=data; 67 tmp->_next=NULL; 68 return tmp; 69 } 71 void init_list(node_pp phead) 72 { 73 *phead=buy_node(0); 74 } 75 76 void push_node(data_type data) 77 { 78 79 if(head->_next==NULL) 80 head->_next=buy_node(data); 81 else{ 82 node_p tmp=buy_node(data); 83 tmp->_next=head->_next; 84 head->_next=tmp; 85 } 86 } 87 88 89 int pop_node(data_type *data) 90 { data_type ret=0; 91 92 if(head->_next==NULL) 93 return *data; else{ 95 node_p tmp=head->_next; 96 head->_next=tmp->_next; 97 *data=tmp->_data; 98 free(tmp); 99 } 100 return *data; 101 } 102 int main() 103 { 104 105 init_list(&head); 106 pthread_cond_init(&cond,NULL); 107 pthread_mutex_init(&lock,NULL); 108 pthread_t tid1,tid2; 109 pthread_create(&tid1,NULL,producter,NULL); 110 pthread_create(&tid2,NULL,consumer,NULL); 111 pthread_join(tid1,NULL); 112 pthread_join(tid2,NULL); 113 pthread_cond_destroy(&cond); 114 pthread_mutex_destroy(&lock); 115 return 0; }
運(yùn)行結(jié)果:
結(jié)果分析:
生產(chǎn)者生產(chǎn)出一個(gè)數(shù)據(jù)之后消費(fèi)者才能消費(fèi),當(dāng)鏈表里沒(méi)有數(shù)據(jù)時(shí),消費(fèi)者就等待對(duì)應(yīng)的條件變量和鎖,直到他們被釋放消費(fèi)者才能進(jìn)去消費(fèi)。
擴(kuò)展:多消費(fèi)者與多生產(chǎn)者問(wèn)題
10 pthread_mutex_t plock=PTHREAD_MUTEX_INITIALIZER; 11 pthread_mutex_t conlock=PTHREAD_MUTEX_INITIALIZER; 12 void push_node(data_type data); 13 int pop_node(); 14 void* producter(void* arg) 15 { 16 data_type i=0; 17 while(1) 18 { sem_wait(&sem_product); 19 pthread_mutex_lock(&plock); 20 i++; 21 push_node(i); 22 sleep(2); 23 pthread_mutex_unlock(&plock); 24 sem_post(&sem_consume); 25 printf("product done......\n"); 26 sleep(2); 27 pthread_cond_signal(&cond); 28 sleep(2); 29 30 } 31 32 } 33 void *consumer(void* arg) 34 { 35 data_type res=-1; 36 while(1) 37 { 38 sem_wait(&sem_consume); 39 pthread_mutex_lock(&conlock); 40 while(-1==pop_node(&res)) 41 { 42 pthread_cond_wait(&cond,&plock); 43 } 44 res=pop_node(&res); 45 printf("consumer data: %d\n",res); 46 sleep(2); 47 pthread_mutex_unlock(&conlock); 48 49 sem_post(&sem_product); 50 51 pthread_cond_signal(&cond); 52 53 sleep(2); 54 55 }
再來(lái)引入一概念:POSIX版本下的信號(hào)量-semaphore
這個(gè)信號(hào)量也相當(dāng)于一個(gè)計(jì)數(shù)器,記錄當(dāng)前資源的數(shù)量。其進(jìn)行的是PV 操作。
有關(guān)于信號(hào)量的函數(shù):
sem_t sema;//定義一個(gè)信號(hào)量
int sem_init(sem_t *sem, int pshared, unsigned int value);//初始化信號(hào)量
int sem_destroy(sem_t *sem);//銷毀信號(hào)量
例子:
定義一個(gè)環(huán)形buf讓生產(chǎn)者生產(chǎn)數(shù)據(jù),消費(fèi)者消費(fèi)數(shù)據(jù),生產(chǎn)者不能將消費(fèi)者套圈,消費(fèi)者也不能超過(guò)消費(fèi)者。
1 #include<stdio.h>
2 #include<semaphore.h>
3 #include<pthread.h>
4 #define _SIZE_ 20
5 sem_t blank;
6 sem_t data;
7 int buf[_SIZE_];
8 void *product(void*arg)
9 {
10 int index=0;
11 int count=0;
12 while(1)
13 {
14 sem_wait(&blank);//申請(qǐng)格子
15 buf[index]=count++;
16 sem_post(&data);//釋放數(shù)據(jù)
17 sleep(10);
18 index++;
19 index%=_SIZE_;
20 }
}
25 void* consume(void* arg)
26 {
27 int index=0;
28 int count=0;
29 while(1)
30 {
31 sem_wait(&data);//申請(qǐng)數(shù)據(jù)
32 count=buf[index];
33 printf("consume data: %d\n",count);
34 sem_post(&blank);//釋放格子
35 sleep(5);
36 index++;
37 index%=_SIZE_;
38 }
41 }
42 int main()
43 {
44 pthread_t tid1,tid2;
45 pthread_create(&tid1,NULL,product,NULL);
46 pthread_create(&tid2,NULL,consume,NULL);
47 sem_init(&blank,0,_SIZE_);//有20個(gè)格子的數(shù)量
48 sem_init(&data,0,0);
49 pthread_join(tid1,NULL);
50 pthread_join(tid2,NULL);
51 sem_destroy(&blank);
52 sem_destroy(&data);
53 return 0;
54 }
程序分析: 這個(gè)程序就滿足上述條件,生產(chǎn)者不會(huì)將消費(fèi)者套圈,因?yàn)樾盘?hào)量在記錄格子的數(shù)量,同樣的消費(fèi)者也不會(huì)超過(guò)生產(chǎn)者,因?yàn)橄M(fèi)的時(shí)候數(shù)據(jù)在減少。
網(wǎng)站標(biāo)題:線程同步與互斥之條件·變量
網(wǎng)頁(yè)路徑:http://aaarwkj.com/article12/pjcsgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、域名注冊(cè)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站設(shè)計(jì)、定制網(wǎng)站、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)