Qt - 生产者和消费者模型示例

简介

使用条件变量,信号量,两种示例方式去实现生产者和消费者模型

 

1、条件变量   QWaitCondition

  1 #ifndef MUTEXWAITCONDITION
  2 #define MUTEXWAITCONDITION
  3 
  4 #include <QCoreApplication>
  5 #include <iostream>
  6 #include <QThread>
  7 #include <QMutex>
  8 #include <QWaitCondition>
  9 
 10 using namespace std;
 11 
 12 class MutexWaitCondition {
 13 public:
 14     //预计生产(或消费)数量
 15     int loopCount;
 16     //当前产品数量
 17     int product;
 18     //仓库能容纳的最大产品数量
 19     int capacity;
 20 
 21     QMutex mutex;
 22     /*
 23      The QWaitCondition class provides a condition variable for synchronizing threads
 24      QWaitCondition类为线程同步提供了一个条件变量
 25      */
 26     QWaitCondition productIsNotFull;
 27     QWaitCondition productIsNotEmpty;
 28 
 29     //生产者
 30     class Producer : public QThread {
 31     public:
 32         Producer(MutexWaitCondition *manager) : QThread() {
 33             this->manager = manager;
 34         }
 35     protected:
 36         void run() {
 37             for(int i=0; i<manager->loopCount; i++) {
 38                 manager->mutex.lock();
 39                 while(manager->product == manager->capacity) {
 40                     /*
 41                      bool QWaitCondition::wait(QReadWriteLock * lockedReadWriteLock, unsigned long time = ULONG_MAX)
 42                      Releases the lockedReadWriteLock and waits on the wait condition
 43                      释放该锁,并且阻塞当前线程,直到条件满足(即调用wake方法被唤醒)
 44                      */
 45                     manager->productIsNotFull.wait(&manager->mutex);
 46                 }
 47                 manager->product++;   //当前产品数量++之前产品就要入队
 48                 //cout<<"P";
 49                 cout<<i<<".P="<<manager->product<<", ";
 50                 manager->productIsNotEmpty.wakeAll();
 51                 manager->mutex.unlock();
 52             }
 53         }
 54     private:
 55         MutexWaitCondition *manager;
 56     };
 57 
 58     //消费者
 59     class Consumer : public QThread {
 60     public:
 61         Consumer(MutexWaitCondition *manager) : QThread() {
 62             this->manager = manager;
 63         }
 64     protected:
 65         void run() {
 66             for(int i=0; i<manager->loopCount; i++) {
 67                 manager->mutex.lock();
 68                 while(manager->product == 0) {
 69                     manager->productIsNotEmpty.wait(&manager->mutex);
 70                 }
 71                 manager->product--;   //当前产品数量--之前产品就要出队
 72                 //cout<<"C";
 73                 cout<<i<<".C="<<manager->product<<", ";
 74                 manager->productIsNotFull.wakeAll();
 75                 manager->mutex.unlock();
 76             }
 77         }
 78     private:
 79         MutexWaitCondition *manager;
 80     };
 81 
 82 //无修饰的方法,默认是private的
 83 public:
 84     void test(int loopCount, int capacity)
 85     {
 86         this->loopCount = loopCount;
 87         this->capacity = capacity;
 88         this->product = 0;
 89 
 90         Producer producer(this);
 91         Consumer consumer(this);
 92         //thread.start会调用thread内部的run方法
 93         producer.start();
 94         consumer.start();
 95         /*
 96          Blocks the thread until either of these conditions is met:
 97          阻塞该线程直到所有条件都满足
 98          */
 99         producer.wait();
100         consumer.wait();
101         cout<<endl;
102     }
103 };
104 #endif // MUTEXWAITCONDITION

 

2、信号量   QSemaphore

  1 #ifndef SEMAPHOREMUTEX
  2 #define SEMAPHOREMUTEX
  3 
  4 #include <QCoreApplication>
  5 #include <iostream>
  6 #include <QThread>
  7 #include <QSemaphore>
  8 //注意:网上很多Semaphore不用mutex的做法都是错误的
  9 #include <QMutex>
 10 
 11 using namespace std;
 12 
 13 class SemaphoreMutex {
 14 public:
 15     //预计生产(或消费)数量
 16     int loopCount;
 17     //当前产品数量: productSemphore.avaliable()
 18     //int product;
 19     //仓库能容纳的最大产品数量
 20     int capacity;
 21 
 22     QMutex mutex;
 23     /*
 24      The QSemaphore class provides a general counting semaphore
 25      QSemaphore类提供了一个通用的计数信号量
 26      */
 27     QSemaphore *productSemphore;
 28     QSemaphore *leftSpaceSemaphore;
 29 
 30     //生产者
 31     class Producer : public QThread {
 32     public:
 33         Producer(SemaphoreMutex *manager) : QThread() {
 34             this->manager = manager;
 35         }
 36     protected:
 37         void run() {
 38             for(int i=0; i<manager->loopCount; i++) {
 39                 /*
 40                  Tries to acquire n resources guarded by the semaphore. If n > available(), this call will block until enough resources are available.
 41                  尝试去获取(减去)n个被信号量控制的资源。如果n>可用资源数量,它就会阻塞直到有足够的资源为止。
 42                  */
 43                 manager->leftSpaceSemaphore->acquire();
 44                 //之所以lock要在acquire后面是因为: 如果消费者拿到了锁,那么又没有商品,那么久会导致死锁
 45                 manager->mutex.lock();   //加锁之后产品就要入队,然后再release
 46                 manager->productSemphore->release();
 47                 //cout<<"P";
 48                 cout<<i<<".P="<<manager->productSemphore->available()<<", ";
 49                 manager->mutex.unlock();
 50             }
 51         }
 52     private:
 53         SemaphoreMutex *manager;
 54     };
 55 
 56     //消费者
 57     class Consumer : public QThread {
 58     public:
 59         Consumer(SemaphoreMutex *manager) : QThread() {
 60             this->manager = manager;
 61         }
 62     protected:
 63         void run() {
 64             for(int i=0; i<manager->loopCount; i++) {
 65                 manager->productSemphore->acquire();
 66                 manager->mutex.lock();   //加锁之后产品就要出队,然后再release
 67                 manager->leftSpaceSemaphore->release();
 68                 //cout<<"C";
 69                 cout<<i<<".C="<<manager->productSemphore->available()<<", ";
 70                 manager->mutex.unlock();
 71             }
 72         }
 73     private:
 74         SemaphoreMutex *manager;
 75     };
 76 
 77 //无修饰的方法,默认是private的
 78 public:
 79     void test(int loopCount, int capacity)
 80     {
 81         this->loopCount = loopCount;
 82         this->capacity = capacity;
 83 
 84         //参数为: 信号量的当前值
 85         productSemphore = new QSemaphore(0);
 86         leftSpaceSemaphore = new QSemaphore(capacity);
 87 
 88         Producer producer(this);
 89         Consumer consumer(this);
 90         //thread.start会调用thread内部的run方法
 91         producer.start();
 92         consumer.start();
 93         /*
 94          Blocks the thread until either of these conditions is met:
 95          阻塞该线程直到所有条件都满足
 96          */
 97         producer.wait();
 98         consumer.wait();
 99         cout<<endl;
100     }
101 };
102 
103 #endif // SEMAPHOREMUTEX

 

posted @ 2020-10-28 14:46  Citrusliu  阅读(1861)  评论(0编辑  收藏  举报