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;
//}本文出自 “momo就是辣么萌” 博客,请务必保留此出处http://momo462.blog.51cto.com/10138434/1828105
mutex&condition variable 黄金搭档之 多消费者多生产者
原文:http://momo462.blog.51cto.com/10138434/1828105