Condition Variable都会搭配一个Mutex来用.我们知道Mutex的普通意义上是维持一个互斥变量,从而保证一个或一组操作的原子性.同样,简单的说Mutex加在Condition Variable上也是为了保证它的原子性了.Condition Variable,有条件的唤醒机制.最经典不过的就是生产--消息者模型了.但有一个细节,消费者需要有"产品"才能继续它的消费行为,因此当消费者发现"产品"被消费完了?它该怎么办?没错,普通情况下它就会进入等待挂起状态.但这一状态什么时候才能结束?又是谁来告诉它有"产品"可消费呢?没错,这个时候消费者就是在等待"有产品可消费"这一条件才会苏醒.这个时候我们就能用到Condition Variable了.
1、代码:c版本 一个消费者-一个生产者
#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); //1、释放mutex 2、阻塞等待 3、被唤醒,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; //}
2、代码 c版本 多消费者--多生产者
#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); //1、释放mutex 2、阻塞等待 3、被唤醒,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; //}
mutex&condition variable 黄金搭档之 多消费者多生产者
时间: 2024-10-27 18:09:09