zoukankan      html  css  js  c++  java
  • 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
    博客园文作者:Citrusliu 博文地址:https://www.cnblogs.com/citrus
  • 相关阅读:
    Mysql数据库快速备份还原-mysqldump
    写给年轻人的交友和人脉建议
    令人担忧的趋势:科技崇拜与人文失落
    高情商的特征
    高情商与朋友圈
    数据库临时表空间设置
    oracle 临时表空间的增删改查
    语言表达能力写作能力决定一个人的发展和未来
    一个人如何从平庸到优秀,再到卓越?
    06.堆排序
  • 原文地址:https://www.cnblogs.com/citrus/p/13891061.html
Copyright © 2011-2022 走看看