QSemaphore 类例子
2015-10-20 14:00
218 查看
QSemaphore 能够提供类似于生产者消费者的模式,既一个生产者进行生成,另一个消费者进行消费。(在多线程中保护多个数据的一个类)
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
[cpp] view
plaincopy
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
plaincopy
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
plaincopy
/// \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
plaincopy
#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
plaincopy
///////////////// 生产者 //////////////////////////////
/// \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
plaincopy
/////////// 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个资源
}
}
例子下载
FROM: http://blog.csdn.net/qyvlik/article/details/44138343
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
[cpp] view
plaincopy
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
plaincopy
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
plaincopy
/// \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
plaincopy
#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
plaincopy
///////////////// 生产者 //////////////////////////////
/// \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
plaincopy
/////////// 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个资源
}
}
例子下载
FROM: http://blog.csdn.net/qyvlik/article/details/44138343
相关文章推荐
- HTTP状态码
- IOS项目集成ShareSDK实现第三方登录、分享、关注等功能
- 6月读书分享-《番茄工作法图解》
- CocoaPods详解之----使用篇
- BZOJ 3993 [SDOI2015]星际战争 二分+最大流
- ssh_exchange_identification: Connection closed by remote hos
- 如何删除百度搜索结果
- iOS工作中的问题-----navigationBar透明方法、遮挡UIViewController、UITableViewController 视图解决方法
- QT 中的生产者和消费者信号量
- 暴风一号1kb病毒又称快捷方式病毒
- 利用Field获取图片
- 20135323符运锦----家庭作业2.76
- DPM 2012 SP1---安装并部署DPM 2012 SP1服务器
- 为快速开发平台一级菜单加入功能导航页
- 单节点配置SecondaryNameNode
- [转]七个对我最好的职业建议(精简版)--Nicholas C. Zakas
- KERNEL中MCE处理流程(一) - 关于PR_MCE_KILL_EARLY的处理 (基于Kernel 4.3-rc3)
- Spring学习笔记(一)加载xml配置文件的方式
- div边框加阴影效果的css
- 用window.print()打印指定div里面的内容(转载的)