码迷,mamicode.com
首页 > 其他好文 > 详细

mutex&condition variable 黄金搭档之 多消费者多生产者

时间:2016-07-20 19:49:31      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:linux   mutex   condition variable   多生产者   多消费者   

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 黄金搭档之 多消费者多生产者

标签:linux   mutex   condition variable   多生产者   多消费者   

原文地址:http://momo462.blog.51cto.com/10138434/1828105

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!