QSemaphore 类例子
更新于2015-03-08 22:55:04
QSemaphore 能够提供类似于生产者消费者的模式,既一个生产者进行生成,另一个消费者进行消费。(在多线程中保护多个数据的一个类)
具体先看看QSemaphore 的介绍吧~
QSemaphore 它的成员函数是
-
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 )
下面举生产者-消费者例子说明
-
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 的描述
-
/// \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
-
#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 对象的工作量
-
/ 生产者 //
-
/// \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();
-
}
-
}
===============================================
消费者,就仅仅打印数据了
-
/// 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个资源
-
}
-
}
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#csdnc-thumbsup"></use> </svg><span class="name">点赞</span> <span class="count"></span> </a></li> <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-Collection-G"></use> </svg><span class="name">收藏</span></a></li> <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-fenxiang"></use> </svg>分享</a></li> <!--打赏开始--> <!--打赏结束--> <li class="tool-item tool-more"> <a> <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg> </a> <ul class="more-box"> <li class="item"><a class="article-report">文章举报</a></li> </ul> </li> </ul> </div> </div> <div class="person-messagebox"> <div class="left-message"><a href="https://blog.csdn.net/qyvlik"> <img src="https://profile.csdnimg.cn/D/0/1/3_qyvlik" class="avatar_pic" username="qyvlik"> </a></div> <div class="middle-message"> <div class="title"><span class="tit"><a href="https://blog.csdn.net/qyvlik" data-report-click="{"mod":"popu_379"}" target="_blank">qyvlik</a></span> </div> <div class="text"><span>发布了165 篇原创文章</span> · <span>获赞 166</span> · <span>访问量 37万+</span></div> </div> <div class="right-message"> <a href="https://bbs.csdn.net/topics/395530398" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板 </a> <a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a> </div> </div> </div> </article>