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