mutex&condition variable 黃金搭檔之 多消費者多生產者

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;
//}


wKiom1ePLD7i4DzrAABMQWIQM8U426.png

二、代碼 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;
//}

wKiom1ePK4eDJS7OAABGWfG7rAA929.png

相關文章
相關標籤/搜索