Condition Variable都會搭配一個Mutex來用.咱們知道Mutex的普通意義上是維持一個互斥變量,從而保證一個或一組操做的原子性.一樣,簡單的說Mutex加在Condition Variable上也是爲了保證它的原子性了.Condition Variable,有條件的喚醒機制.最經典不過的就是生產--消息者模型了.但有一個細節,消費者須要有"產品"才能繼續它的消費行爲,所以當消費者發現"產品"被消費完了?它該怎麼辦?沒錯,普通狀況下它就會進入等待掛起狀態.但這一狀態何時才能結束?又是誰來告訴它有"產品"可消費呢?沒錯,這個時候消費者就是在等待"有產品可消費"這一條件纔會甦醒.這個時候咱們就能用到Condition Variable了.node
一、代碼:c版本 一個消費者-一個生產者ide
#include <stdio.h> //#include "debug.h" #include <stdlib.h> #include <pthread.h> typedef struct node { int data; struct node *next; }node_t,*node_p,**node_pp; node_p head=NULL; void alloc_node(node_pp node,int data) { *node=(node_p)malloc(sizeof(node_t)); node_p newnode=*node; newnode->data=data; //printf("alloc :%d ",newnode->data); newnode->next=NULL; } void init() { alloc_node(&head,0); } int is_empty() { if(head->next==NULL) { return 0; } else return -1; } int push_front(node_p head,int data) { node_p tmp; alloc_node(&tmp,data); if(tmp==NULL) { return -1; } tmp->next=head->next; head->next=tmp; return 0; } void pop_front(node_p head,int *data) { if(is_empty()==0) { return; } node_p tmp=head->next; *data=tmp->data; head->next=tmp->next; free(tmp); } void show(node_p head) { node_p phead=head->next; while(phead) { printf("%d ",phead->data); phead=phead->next; } printf("\n"); } pthread_cond_t cond1; pthread_mutex_t lock1; //消費者等生產者通知 void *consumer(void *arg) { while(1) { pthread_mutex_lock(&lock1); while(is_empty(head)==0) { printf("consumer%d is not ready!\n",(int)arg); //一、釋放mutex 二、阻塞等待 三、被喚醒,metux得到 pthread_cond_wait(&cond1,&lock1); printf("consumer%d is ready!\n",(int)arg); } int data=0; pop_front(head,&data); printf("consumer%d is done...%d\n",(int)arg,data); pthread_mutex_unlock(&lock1); sleep(1); } } //生產者生產 void *producter(void *arg) { while(1) { pthread_mutex_lock(&lock1); int data=rand()%1234; push_front(head,data); pthread_mutex_unlock(&lock1); printf("producter%d is done ...%d\n",(int)arg,data); sleep(1); pthread_cond_signal(&cond1); } } int main() { init(head); pthread_t id1,id2; pthread_cond_init(&cond1,NULL); pthread_mutex_init(&lock1,NULL); pthread_create(&id1,NULL,consumer,NULL); pthread_create(&id2,NULL,producter,NULL); pthread_join(id1,NULL); pthread_join(id2,NULL); pthread_cond_destroy(&cond1); pthread_mutex_destroy(&lock1); } //int main() //{ // init(head); // int i=0; // for(i;i<10;i++) // { // push_front(head,i); // show(head); // // } // for(i=0;i<10;i++) // { // int a; // pop_front(head,&a); // show(head); // } // return 0; //}
二、代碼 c版本 多消費者--多生產者spa
#include <stdio.h> //#include "debug.h" #include <stdlib.h> #include <pthread.h> typedef struct node { int data; struct node *next; }node_t,*node_p,**node_pp; node_p head=NULL; void alloc_node(node_pp node,int data) { *node=(node_p)malloc(sizeof(node_t)); node_p newnode=*node; newnode->data=data; //printf("alloc :%d ",newnode->data); newnode->next=NULL; } void init() { alloc_node(&head,0); } int is_empty() { if(head->next==NULL) { return 0; } else return -1; } int push_front(node_p head,int data) { node_p tmp; alloc_node(&tmp,data); if(tmp==NULL) { return -1; } tmp->next=head->next; head->next=tmp; return 0; } void pop_front(node_p head,int *data) { if(is_empty()==0) { return; } node_p tmp=head->next; *data=tmp->data; head->next=tmp->next; free(tmp); } void show(node_p head) { node_p phead=head->next; while(phead) { printf("%d ",phead->data); phead=phead->next; } printf("\n"); } pthread_cond_t cond1; pthread_mutex_t lock1; //消費者等生產者通知 void *consumer(void *arg) { while(1) { pthread_mutex_lock(&lock1); while(is_empty(head)==0) { printf("consumer%d is not ready!\n",(int)arg); //一、釋放mutex 二、阻塞等待 三、被喚醒,metux得到 pthread_cond_wait(&cond1,&lock1); printf("consumer%d is ready!\n",(int)arg); } int data=0; pop_front(head,&data); printf("consumer%d is done...%d\n",(int)arg,data); pthread_mutex_unlock(&lock1); sleep(1); } } //生產者生產 void *producter(void *arg) { while(1) { pthread_mutex_lock(&lock1); int data=rand()%1234; push_front(head,data); pthread_mutex_unlock(&lock1); printf("producter%d is done ...%d\n",(int)arg,data); sleep(1); pthread_cond_signal(&cond1); } } int main() { init(head); pthread_t id1,id2,id3,id4; pthread_cond_init(&cond1,NULL); pthread_mutex_init(&lock1,NULL); pthread_create(&id1,NULL,consumer,(void *)1); pthread_create(&id3,NULL,consumer,(void *)2); pthread_create(&id2,NULL,producter,(void*)1); pthread_create(&id4,NULL,producter,(void*)2); pthread_join(id1,NULL); pthread_join(id2,NULL); pthread_join(id3,NULL); pthread_join(id4,NULL); pthread_cond_destroy(&cond1); pthread_mutex_destroy(&lock1); } //int main() //{ // init(head); // int i=0; // for(i;i<10;i++) // { // push_front(head,i); // show(head); // // } // for(i=0;i<10;i++) // { // int a; // pop_front(head,&a); // show(head); // } // return 0; //}