信号量和条件变量(+互斥量)实现生产消费者练习

信号量:

    1 #include<stdio.h>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    2 #include<iostream>
    3 #include<pthread.h>
    4 #include<semaphore.h>
    5 #include<vector>
    6 using namespace std;
    7 #define  MAX_CAP 5
    8 #define  PRO 5
    9 #define  CUS 5
   10 
   11 class RingQueue{
   12   private:
   13     vector<int> arr;
   14     int _start;
   15     int _end;
   16     int _capacity;
   17     sem_t _lock;
   18     sem_t _data;
   19     sem_t _idle;
   20 
   21   public:
   22     RingQueue(int cap=MAX_CAP)
   23       :_start(0)
   24        , _end(0)
W> 25        , _capacity(cap)
   26        ,arr(cap)
   27   {
   28     sem_init(&_lock, 0, 1);
   29     sem_init(&_data, 0, 0);
   30     sem_init(&_idle, 0, cap);
   31 
   32   }
   33 
   34     ~RingQueue(){
   35       sem_destroy(&_lock);
   36       sem_destroy(&_idle);
   37       sem_destroy(&_data);
   38 
   39     }
   40 
   41     void push(int data){
   42       sem_wait(&_idle);
   43       sem_wait(&_lock);
   44       arr[_start] = data;
   45       _start=(_start+1)%_capacity;
   46       sem_post(&_lock);
   47       sem_post(&_data);
   48 
   49     }
   50     void pop(int* data){
   51       sem_wait(&_data);
   52       sem_wait(&_lock);
   53       *data=arr[_end];
   54       //arr[_end] = *data;
   55       _start=(_end+1)%_capacity;
   56       sem_post(&_lock);
   57       sem_post(&_idle);
   58 
   59 
   60     }
   61 
   62 };
   63 
   64 void* pro(void* arg){
   65   RingQueue* que = (RingQueue*)arg;
   66 
   67   int i = 0;
   68   while (1){
   69     que->push(i);
W> 70     printf("%p-push data-%d\n", pthread_self(), i++);
   71 
   72   }
   73   return NULL;
   74 
   75 }
   76 
   77 void* cus(void* arg){
   78   RingQueue* que = (RingQueue*)arg;
   79   //int data;
   80   while (1){
   81     int data;
   82     que->pop(&data);
W> 83     printf("%p-get data-%d\n", pthread_self(), data);
   84 
   85   }
   86   return NULL;
   87 };
   88 int main(){
   89   RingQueue q;
   90   pthread_t ar1[PRO];
   91   pthread_t ar2[CUS];
   92   int ret = 0;
   93   for (int i = 0; i < PRO; ++i){
   94     ret=pthread_create(&ar1[i], NULL, pro, &q);//传地址
   95     if (ret != 0) {
   96       printf("thread create error\n");
   97       return -1;
   98 
   99     }
  100 
  101   }
  102   for (int i = 0; i < PRO; ++i){
  103     ret=pthread_create(&ar2[i], NULL, cus, &q);
  104     if (ret != 0) {
  105       printf("thread create error\n");
  106       return -1;
  107 
  108     }
  109 
  110   }
  111   for (int i = 0; i < PRO; i++) {
  112     pthread_join(ar1[i], NULL);
  113     pthread_join(ar2[i], NULL);
  114 
  115   }
  116   return 0;
  117 }

条件变量

    1 #include<cstdio>                                                                                                                                                                                                                                                                                                                                                                                                                
    2 #include<iostream>
    3 #include<pthread.h>
    4 #include<queue>
    5 #include<unistd.h>
    6 #define FIRSTNUM 5
    7 class blockQueue{
    8 private:
    9   std::queue<int> _q;
   10   pthread_mutex_t mymutex;
   11   pthread_cond_t provider;
   12   pthread_cond_t consumer;
   13   int _capacity;//不能叫capacity
   14 public:
   15   blockQueue(int cap=FIRSTNUM)
   16     :_capacity(cap) //将参数传给类内成员capacity 
   17   {
   18     //queue<int> q;//队列已经定义在了成员变量中
   19     pthread_mutex_init(&mymutex,NULL);
   20     pthread_cond_init(&provider,NULL);
   21     pthread_cond_init(&consumer,NULL);
   22     //capacity=FIRSTNUM;
   23     }
   24 
   25   ~blockQueue(){
   26     pthread_mutex_destroy(&mymutex);
   27     pthread_cond_destroy(&provider);
   28     pthread_cond_destroy(&consumer);
   29     //block会调用queue的析构清理queue的资源
   30     }
   31   //放入数据
   32   bool push(const int& data){
   33     //int i=0;//这个需要写在线程函数里,push是插入,这样写就只能插入1!!!!!
   34     pthread_mutex_lock(&mymutex);
W> 35     while(_capacity == _q.size()){
   36     //while(capacity==q.capacity()){//...queue是deque实现的,没有容量这个概念.....
   37       pthread_cond_wait(&provider,&mymutex);
   38     }
   39     _q.push(data);
   40     //q.push(i++);
   41     //cout<<"push data--"<<endl;
   42     pthread_cond_signal(&consumer);
   43     pthread_mutex_unlock(&mymutex);
   44     //函数返回值!!没写
   45     return true;
   46   }
   47 
   48   bool pop(int& data){
   49     pthread_mutex_lock(&mymutex);
   50     //pthread_mutex_lock(&consumer);//锁变量?
   51     while(_q.empty()){
   52       pthread_cond_wait(&consumer,&mymutex);
   53     }
   54     data=_q.front();
   55     //p.front()=data;//data用来获取front,写反了...
   56     _q.pop();
   57     pthread_cond_signal(&provider);
   58     pthread_mutex_unlock(&mymutex);
   59     //函数返回值!!没写
   60     return true;
   61   }
   62 
   63 };
   64 
   65 void* pro (void* arg){
   66 blockQueue* bq=(blockQueue*)arg;
   67 int i=0;
   68   //pthread_mutex_lock(&mumutex);//模拟生产消费者模型需要线程安全的队
   69   //列,所以实现线程安全需要在类里而不是这里!!!
   70   //while(capacity==q.capacity){
   71   //  pthread_cond_wait(&provider,&mumutex);
   72   //}
   73   while(1){//不停地写
   74     bq->push(i);//回掉函数的传参就是一个队列的指针
   75   //p.push(i++);
   76  //pthread_cond_signal(&consumer);
   77  //pthread_mutex_unlock(&mymutex);
W> 78  printf("%p-push data:%d\n", pthread_self(), i++);
   79  //  std::cout<<"push data"<<i<<std::endl;
   80   }
   81   return NULL;
   82 }
   83 
   84 
   85 void* cus (void* arg){
   86   blockQueue* bq=(blockQueue*)arg;
   87   //pthread_mutex_lock(&consumer);
   88   //while(q.empty()){
   89   //  pthread_cond_wait(&consumer,&mumutex);
   90   //}
   91   while(1){
   92   int data;//建立数据
   93 
   94     //data=bq->front();
   95   //bq->pop();
   96   bq->pop(data);//pop为有参函数,参数保存了删除的内容
W> 97   printf("%p-get data:%d\n", pthread_self(), data);
   98   //std::cout<<"get data"<<data<<std::endl;
   99   }
  100   //pthread_cond_signal(&provider);
  101   //pthread_mutex_unlock(&mymutex);
  102   return NULL;//void*要写返回值,代表不关心返回值
  103 }
  104 
  105 
W>106 int main(int argc,char* argv[]){
  107   blockQueue q;
  108   int count=4;
  109   //queue<int> q;//blockqueue都写好了.....
  110   pthread_t ptid[4];
  111   pthread_t ctid[4];
  112   int ret;
  113   for(int i=0;i<count;++i){
  114     ret=pthread_create (&ctid[i],NULL,cus,&q);
  115     if(ret!=0){
  116     return -1;
  117     }
  118   }
  119   
  120   for(int i=0;i<count;++i){
  121     ret=pthread_create(&ptid[i],NULL,pro,&q);
  122     if(ret!=0){
  123       return -1;
  124     }
  125   }
  126 
  127   for(int i=0;i<4;++i){
  128   pthread_join(ptid[i],NULL);
  129   pthread_join(ctid[i],NULL);
  130   
  131   }
  132   return 0;
  133 }                           

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值