Linux------生产者与消费者模型

  • 什么是生产者与消费者模型
    一个场所, 两种角色, 三种关系

    • 两种角色: 生产者与消费者
    • 三种关系:
      1.同步关系
      2.互斥关系
      3.同步加互斥关系
  • 为什么使用这种模型
    1.解耦合
    2.支持忙闲不均
    3.支持并发

  • 实现
    1.基于信号量来实现生产者与消费者模型

/*
*   文件名称: 
*   *   创 建 
*   *   创建日期:
*   *   描    述:使用信号量实现生产者与消费者模型 , 唤醒队列 
*   ================================================================*/
#include <iostream>
#include <vector>
#include <thread>
#include <semaphore.h>

#define MAXQ 10

class RingQueue
{
  public:
    RingQueue(int maxq = MAXQ)
      :_queue(maxq)
      ,_capacity(maxq)
  {
    sem_init(&_lock , 0 , 1);//第二个参数0/1表示用于线程间或进程间,0为线程
    sem_init(&_idle_space , 0 , maxq);
    sem_init(&_data_space, 0 , 0);
  }
    ~RingQueue()
    {
      sem_destroy(&_lock);
      sem_destroy(&_data_space);
      sem_destroy(&_idle_space);
    }
    bool QueuePush(int data)
    {
      sem_wait(&_idle_space);//判断队列是否满了
      sem_wait(&_lock);//计数-1 加锁
      _queue[_step_write] = data;
      _step_write = (_step_write + 1) % _capacity;//写指针向后移动
      sem_post(&_lock);//进行计数+1 解锁
      sem_post(&_data_space);//数据空间+1
      return true;
    }
    bool QueuePop(int &data)
    {
      sem_wait(&_lock);
      sem_wait(&_data_space);
      data = _queue[_step_read];
      _step_read = (_step_read + 1) % _capacity;
      sem_post(&_lock);
      sem_post(&_idle_space);//空闲空间多一个 唤醒生产者
      return true;
    }

  private:
    std::vector<int> _queue;
    int _capacity;//节点限制
    int _step_read;//读指针
    int _step_write;//写指针
    sem_t _lock;
    sem_t _idle_space;//空闲空间计数
    sem_t _data_space;//数据空间计数
};

void thr_producer(RingQueue *q)
{
  int data = 0;
  while(1)
  {
    q->QueuePush(data);
    std::cout << "put data------" << data++ << std::endl;
  }
  return;
}

void thr_consumer(RingQueue *q)
{
  int data = 0 ;
  while(1)
  {
    q->QueuePop(data);
    std::cout << "get data--"<< data << std::endl;
  }
  return;
}

int main()
{
  RingQueue q;
  std::vector<std::thread> list_con(4);
  std::vector<std::thread> list_pro(4);
  for(int i = 0 ; i < 4 ; i++)
  {
    list_pro[i] = std::thread (thr_producer , &q ,std::ref(q));
  }
  for(int i = 0 ; i < 4 ; i++)
  {
    list_con[i] = std::thread(thr_consumer , &q);
  }
  for(int i = 0 ; i < 4 ; i++)
  {
    list_con[i].join();
    list_pro[i].join();
  }
  return 0 ;
}

2.基于互斥锁与条件变量实现生产者与消费者模型

/*=============================================================== 
*   Copyright (C) . All rights reserved.")
*   文件名称: 
*   创 建 者:zhang
*   创建日期:
*   描    述:基于互斥锁与条件变量实现一个线程安全的队列
*       实现生产者与消费者模型 
 ================================================================*/

#include <iostream>
#include <pthread.h>
#include <queue>
#define MAXQ 10

class BlockQueue{
private:
  std::queue<int> _queue;
  int _capacity;
  pthread_mutex_t _mutex;
  pthread_cond_t _cond_productor;
  pthread_cond_t _cond_consumer;
public:
  BlockQueue(int maxq = MAXQ)
    :_capacity(maxq)
  {
    pthread_mutex_init(&_mutex , NULL);
    pthread_cond_init(&_cond_productor , NULL);
    pthread_cond_init(&_cond_consumer , NULL);
  }
  
  ~BlockQueue()
  {
    pthread_mutex_destroy(&_mutex);
    pthread_cond_destroy(&_cond_productor);
    pthread_cond_destroy(&_cond_consumer);
  }

//  bool IsFull()
// {
//    return (_queue.size() == _capacity ? true : false);
//  }
  
  bool QueuePush(int data)
  {
    pthread_mutex_lock(&_mutex);
    while(_queue.size() == _capacity)
    {
      pthread_cond_wait(&_cond_productor , &_mutex);
    }
    _queue.push(data);
    pthread_mutex_unlock(&_mutex);
    pthread_cond_signal(&_cond_consumer);
    return true;
  }
  
  bool QueuePop(int &data)
  {
    pthread_mutex_lock(&_mutex);
    while(_queue.empty())
    {
      pthread_cond_wait(&_cond_consumer , &_mutex);
    }
    data = _queue.front();
    _queue.pop();
    pthread_mutex_unlock(&_mutex);
    pthread_cond_signal(&_cond_productor);
    
    return true;
  }
};

void *thr_consumer(void *arg)
{
  BlockQueue *q = (BlockQueue*)arg;
  int data;
  while(1)
  {
    q->QueuePop(data);
    std::cout << "consumer get a piece of data --"<< data << "\n";
  }
}

void *thr_productor(void *arg)
{
  BlockQueue *q = (BlockQueue*)arg;
  int data = 0;
  while(1)
  {
    q->QueuePush(data);
    std::cout << "productor produces a data" << data ++ << "\n";
  }
  return NULL;
}

#define MAXTHR 1
int main()
{
  pthread_t ctid[MAXTHR] , ptid[MAXTHR];
  int ret , i;

  BlockQueue q;
  for(i = 0 ; i <MAXTHR ; i++)
  {
    ret = pthread_create( &ctid[i] , NULL , thr_consumer , (void*)&q);
    if(ret != 0 )
    {
      std::cout << "creadte thread error \n";
      return -1;
    }
  }
  for(i = 0 ; i < MAXTHR ; i++)
  {
    ret = pthread_create(&ptid[i] , NULL , thr_productor , (void*)&q);
    if(ret != 0)
    {
      std::cout << "creat thread error \n";
      return -1;
    }
  }
  for(i = 0 ;i < MAXTHR ; i++)
  {
    pthread_join(ctid[i] , NULL);
    pthread_join(ptid[i] , NULL);
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值