QSemaphore 能够提供类似于生产者消费者的模式,既一个生产者进行生成,另一个消费者进行消费。(在多线程中保护多个数据的一个类)
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
- QSemaphore ( int n = 0 )
- ~QSemaphore ()
- void acquire ( int n = 1 )
- int available () const
- void release ( int n = 1 )
- bool tryAcquire ( int n = 1 )
- bool tryAcquire ( int n, int timeout )
下面举生产者-消费者例子说明
- const int DataSize = 100000;
- const int BufferSize = 8192;
- char buffer[BufferSize];
-
-
- QSemaphore freeBytes(BufferSize);
- QSemaphore usedBytes;
-
- class Producer : public QThread
- {
- public:
- void run();
- };
-
- void Producer::run()
- {
- qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
- for (int i = 0; i < DataSize; ++i) {
- freeBytes.acquire();
- buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];
- usedBytes.release();
- }
- }
-
-
- class Consumer : public QThread
- {
- public:
- void run();
- };
-
- void Consumer::run()
- {
- for (int i = 0; i < DataSize; ++i) {
- usedBytes.acquire();
- fprintf(stderr, "%c", buffer[i % BufferSize]);
- freeBytes.release();
- }
- fprintf(stderr, "\n");
- }
-
- int main(int argc, char *argv[])
- {
- QCoreApplication app(argc, argv);
- Producer producer;
- Consumer consumer;
- producer.start();
- consumer.start();
- producer.wait();
- consumer.wait();
- return 0;
- }
以上是一对一的模式,一般来说,生产者多于消费者或者消费者多于生产者的情况很常见(消费者为复数或者生产者为复数什么的也很常见的),接下来提供一个复数生产者单数消费者的例子吧~
==============================================
以下是SemaphoresThread 的描述
-
-
-
-
-
-
- #ifndef SEMAPHORESTHREAD_H
- #define SEMAPHORESTHREAD_H
-
- #include <QObject>
- #include <QSemaphore>
- #include <QList>
- #include <QThread>
-
-
- #include <QDebug>
- #include <stdio.h>
-
-
- class SemaphoresThread : public QThread
- {
- Q_OBJECT
-
- public:
- explicit SemaphoresThread(QObject *parent = 0);
- ~SemaphoresThread();
-
- protected:
- static const int BufferSize;
- static const int DataSize;
-
- static QSemaphore freeBytes;
- static QSemaphore usedBytes;
-
- static QList<int> data;
-
- virtual void run() = 0;
-
- };
-
- #endif // SEMAPHORESTHREAD_H
static const int BufferSize; // 总的可被生产者使用的空间大小
static const int DataSize; //
static QSemaphore freeBytes; // 全局静态对象,在生产者中,用于累减可用来生成的资源的空间大小 ; 在消费者中,被累加.
static QSemaphore usedBytes; // 全局静态对象,在生产者中,用于累加可用来生成的资源的空间大小 ; 在消费者中,被累减.
static QList<int> data; // 全局静态数据对象
====================================
我们的Producer类继承自SemaphoresThread
- #ifndef PRODUCER_H
- #define PRODUCER_H
-
- #include "SemaphoresThread.h"
- #include <QMutex>
-
- class Producer : public SemaphoresThread
- {
- Q_OBJECT
- public:
- explicit Producer(QObject *parent = 0);
- ~Producer();
-
- protected:
- void run();
-
- static void addProducer();
- static void removeProducer();
- static int producerCount();
-
- private:
- static int ProducerCount;
- static QMutex mutex;
- };
-
- #endif // PRODUCER_H
增加了两个静态对象,用于记录Producer构造的次数与构造的个数
通过构造的个数来计算每个Producer 对象的工作量
-
-
-
-
- void Producer::run()
- {
- for (int i = 0; i < Producer::DataSize / Producer::producerCount(); ++i) {
- Producer::freeBytes.acquire();
- Producer::data.append(1);
- printf("%d",Producer::data.last());
- fflush(stdout);
- Producer::usedBytes.release();
- }
- }
===============================================
消费者,就仅仅打印数据了
-
-
-
- void Consumer::run()
- {
- for (int i = 0; i < SemaphoresThread::DataSize; ++i) {
- SemaphoresThread::usedBytes.acquire();
-
- printf("%d",Consumer::data.at(i)+1);
- fflush(stdout);
-
- SemaphoresThread::freeBytes.release();
- }
- }