QSemaphore----Qt信号量
2016-10-26 22:10
239 查看
QSemaphore 能够提供类似于生产者消费者的模式,既一个生产者进行生成,另一个消费者进行消费。(在多线程中保护多个数据的一个类)
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
[cpp] view
plain copy
QSemaphore ( int n = 0 )//建立对象时可以给它n个资源
~QSemaphore ()
void acquire ( int n = 1 )// 这个操作一次减少n个资源,如果现有资源不到n个就会阻塞
int available () const //返回当前可用的QSemaphore资源个数
void release ( int n = 1 )//这个操作一次增加n个资源
bool tryAcquire ( int n = 1 )//类似于acquire,但是申请不到n个资源时不会阻塞会立即返回
bool tryAcquire ( int n, int timeout )
下面举生产者-消费者例子说明
[cpp] view
plain copy
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 的描述
[cpp] view
plain copy
/// \author qyvlik
/// \abstract
/// \version 0.0.1
/// \date 2015/03/08
///
#ifndef SEMAPHORESTHREAD_H
#define SEMAPHORESTHREAD_H
#include <QObject>
#include <QSemaphore>
#include <QList>
#include <QThread>
//// print data to the console ///
#include <QDebug>
#include <stdio.h>
//// print data to the console ///
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
[cpp] view
plain copy
#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 function to operator ProducerCount //////////
static void addProducer();
static void removeProducer();
static int producerCount();
private:
static int ProducerCount;
static QMutex mutex;
};
#endif // PRODUCER_H
增加了两个静态对象,用于记录Producer构造的次数与构造的个数
通过构造的个数来计算每个Producer 对象的工作量
[cpp] view
plain copy
///////////////// 生产者 //////////////////////////////
/// \brief Producer::run
/// 通过 Producer::DataSize / Producer::producerCount() 得知每个生产者的工作量
/// 如果 Producer::producerCount() % Producer::DataSize != 0 ;将会发生运行错误!
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();
}
}
===============================================
消费者,就仅仅打印数据了
[cpp] view
plain copy
/////////// run ///////////////////
/// \brief Consumer::run
/// 用来消费 data 中的数据的
void Consumer::run()
{
for (int i = 0; i < SemaphoresThread::DataSize; ++i) {
SemaphoresThread::usedBytes.acquire(); // 这个操作一次减少1个资源,如果现有资源不到1个就会阻塞
printf("%d",Consumer::data.at(i)+1);
fflush(stdout);
SemaphoresThread::freeBytes.release(); // 这个操作一次增加1个资源
}
}
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
[cpp] view
plain copy
QSemaphore ( int n = 0 )//建立对象时可以给它n个资源
~QSemaphore ()
void acquire ( int n = 1 )// 这个操作一次减少n个资源,如果现有资源不到n个就会阻塞
int available () const //返回当前可用的QSemaphore资源个数
void release ( int n = 1 )//这个操作一次增加n个资源
bool tryAcquire ( int n = 1 )//类似于acquire,但是申请不到n个资源时不会阻塞会立即返回
bool tryAcquire ( int n, int timeout )
下面举生产者-消费者例子说明
[cpp] view
plain copy
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 的描述
[cpp] view
plain copy
/// \author qyvlik
/// \abstract
/// \version 0.0.1
/// \date 2015/03/08
///
#ifndef SEMAPHORESTHREAD_H
#define SEMAPHORESTHREAD_H
#include <QObject>
#include <QSemaphore>
#include <QList>
#include <QThread>
//// print data to the console ///
#include <QDebug>
#include <stdio.h>
//// print data to the console ///
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
[cpp] view
plain copy
#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 function to operator ProducerCount //////////
static void addProducer();
static void removeProducer();
static int producerCount();
private:
static int ProducerCount;
static QMutex mutex;
};
#endif // PRODUCER_H
增加了两个静态对象,用于记录Producer构造的次数与构造的个数
通过构造的个数来计算每个Producer 对象的工作量
[cpp] view
plain copy
///////////////// 生产者 //////////////////////////////
/// \brief Producer::run
/// 通过 Producer::DataSize / Producer::producerCount() 得知每个生产者的工作量
/// 如果 Producer::producerCount() % Producer::DataSize != 0 ;将会发生运行错误!
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();
}
}
===============================================
消费者,就仅仅打印数据了
[cpp] view
plain copy
/////////// run ///////////////////
/// \brief Consumer::run
/// 用来消费 data 中的数据的
void Consumer::run()
{
for (int i = 0; i < SemaphoresThread::DataSize; ++i) {
SemaphoresThread::usedBytes.acquire(); // 这个操作一次减少1个资源,如果现有资源不到1个就会阻塞
printf("%d",Consumer::data.at(i)+1);
fflush(stdout);
SemaphoresThread::freeBytes.release(); // 这个操作一次增加1个资源
}
}
相关文章推荐
- Qt信号量QSemaphore
- Qt之线程同步(生产者消费者模式 - QSemaphore)
- QSemaphore 类例子
- 【 error LNK2005: "class QSemaphore freeBytes" (?freeBytes@@3VQSemaphore@@A) 已经在 main.obj 中定义】
- 【Qt多线程之信号量】Qsemaphore
- Qt信号量QSemaphore
- Qt同步线程(比较清楚,而且QMutex QMutexLocker QReadWriteLock QSemaphore QWaitCondition 每个都有例子)
- qt翻译---QSemaphore
- Qt多线程编程一:使用QSemaphore和waitCondition管理一系列资源
- 使用QSemaphore来同步两个线程(QSDK examples)
- Qt 线程同步(QMutex、QWaitCondition、QSemaphore)
- QT——QSemaphore(信号量)
- QT 信号量QSemaphore的使用
- Qt信号量QSemaphore
- Qt之线程同步(生产者消费者模式 - QSemaphore)
- QSemaphore
- Qt之线程同步(生产者消费者模式 - QSemaphore)
- QSemaphore
- QSemaphore 信号量
- Qt多线程编程(3)——QSemaphore的使用