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

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

时间: 2024-10-27 18:09:09

mutex&condition variable 黄金搭档之 多消费者多生产者的相关文章

C++11中的mutex, lock,condition variable实现分析

本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装.不过里面也有很多细节值得学习. std::mutex 先来看下std::mutex: 包增了一个pthread_mutex_t __m_,很简单,每个函数该干嘛就干嘛. class mutex { pthread_mutex_t __m_; public: mutex() _NOEXCEPT {__m

Linux Condition Variable条件变量避免锁冲突

条件变量Condition Variable的一般用法: 唤醒用法: 1 struct { 2 pthread_mutex_t mutex; 3 pthread_cond_t cond; 4 //whatever variables maintain the condition 5 ) var = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, ... };//声明结构体并初始化 6 7 pthread_mutex_lock(&var

关于Condition Variable的一些思考

可能大家都使用过condition variable(之后称cv) 背景不过多做介绍,使用condition variable的时候都要配合mutex使用,那么mutex就是为了什么呢,为什么要用这个东西呢? 为什么要这样设计?mutex多余吗?他是用来保护什么数据呢? ok!让我们来从零开始. condition variable(之后统一叫做cv)的初衷是为了wait某一个东东变成true或false,然后此线程继续进行. 按照此需求,大概的代码应该是这样: //version 1.0 Th

C++11中std condition variable的使用

<condition_variable>是C++标准程序库中的一个头文件,定义了C++11标准中的一些用于并发编程时表示条件变量的类与方法等. 条件变量是并发程序设计中的一种控制结构.多个线程访问一个共享资源(或称临界区)时,不但需要用互斥锁实现独享访问以避免并发错误(称为竞争危害),在获得互斥锁进入临界区后还需要检验特定条件是否成立: (1).如果不满足该条件,拥有互斥锁的线程应该释放该互斥锁,把自身阻塞(block)并挂到(suspend)条件变量的线程队列中 (2).如果满足该条件,拥有

&nbsp; &nbsp; &nbsp; MHVTL安装--搭建备份软件测试环境的黄金搭档

MHVTL安装--搭建备份软件测试环境的黄金搭档 mhvtl download https://sites.google.com/site/linuxvtl2/home#vtl-getting-started VTL OS CENTOS6.5 64bit Backuper Server:Networker8 for Windows Server2008 x64RedHat/CentOS/Scientific Linux/Oracle Linux distributions: 1.安装MHVTL

JavaScript大杂烩8 - 理解文本解析的"黄金搭档"

文本解析"黄金搭档" - String与RegExp对象 文本解析是任何语言中最常用的功能,JavaScript中也是一样,而正则表达式作为最常用的方式,JavaScript也同样是支持的,下面就来看看字符串对象与正则表达式对象的配合. 字符串的恒定性 在正式开始讨论字符串对象的成员之前,我们需要了解一点,那就是:与C#一样,JavaScript 的字符串是不可变的(immutable),String对象定义的方法都不会改变字符串的内容.像toUpperCase这样的方法,返回的是全新

深度学习的黄金搭档:GPU正重塑计算方式(转载)

转载:原文链接 深度学习的黄金搭档:GPU正重塑计算方式 OFweek电子工程网讯 随着神经网络和深度学习研究的不断深入——尤其是语音识别和自然语言处理.图像与模式识别.文本和数据分析,以及其他复杂领域——研究者们不断在寻找新的更好的方法来延伸和扩展计算能力. 几十年来,这一领域的黄金标准一直是高性能计算(HCP)集群,它解决了大量处理能力的问题,虽然成本有点过高.但这种方法已经帮助推动了多个领域的进步,包括天气预测.金融服务,以及能源勘探. 然而,2012 年,一种新的方法出现了.伊利诺伊大学

大型网站网络结构过渡与软件架构的黄金搭档

前言 你可能常常听说,F5.集群.网站架构等名词,却又不知道何为网站架构,更不知一个大型高并发网站的演变过程. 如果你是个JavaEE初级程序员,想明白除了软件开发,你还可以做什么. ---那么,这篇文章可以让你领略一二. 了解数据怎么变大,网站由小向大过渡结构(通过不断硬件的扩充实现大的负载) 1) 静态网站 背景:最开始,我们想做一个小网站,一个静态网页,把自己的个人简历放上去. 需求:需要一个网络空间(在服务器上,这个服务器很多用户一起使用) 结构图: 说明:为了保证服务器数据的安全性,个

Java程序设计之消费者和生产者

新建一个Break类,表示食物数量. public class Break { public static final int MAX = 10; //最多一次性煮十个面包 Stack<Integer> stack = new Stack<Integer>(); public static int food_count = 0; //统计食物的个数 //做面包 public synchronized void make_food(int number){ stack.push(nu