QSemaphore

QSemaphore 类例子

QSemaphore 能够提供类似于生产者消费者的模式,既一个生产者进行生成,另一个消费者进行消费。(在多线程中保护多个数据的一个类)

具体先看看QSemaphore 的介绍吧~

QSemaphore 它的成员函数是


 
 
  1. QSemaphore ( int n = 0 ) //建立对象时可以给它n个资源
  2. ~QSemaphore ()
  3. void acquire ( int n = 1 )// 这个操作一次减少n个资源,如果现有资源不到n个就会阻塞
  4. int available () const //返回当前可用的QSemaphore资源个数
  5. void release ( int n = 1 ) //这个操作一次增加n个资源
  6. bool tryAcquire ( int n = 1 ) //类似于acquire,但是申请不到n个资源时不会阻塞会立即返回
  7. bool tryAcquire ( int n, int timeout )

下面举生产者-消费者例子说明



 
 
  1. const int DataSize = 100000; //要生产的数据个数
  2. const int BufferSize = 8192; //用于盛数据的缓存大小
  3. char buffer[BufferSize];
  4. //要定义两个信号量,一个用于表示自由空间,一个用于表示已用空间
  5. QSemaphore freeBytes(BufferSize); //自由空间初始化大小当然等于缓存大小啦
  6. QSemaphore usedBytes;
  7. class Producer : public QThread
  8. {
  9. public:
  10. void run();
  11. };
  12. void Producer::run()
  13. {
  14. qsrand(QTime( 0, 0, 0).secsTo(QTime::currentTime()));
  15. for ( int i = 0; i < DataSize; ++i) {
  16. freeBytes.acquire(); //申请一个自由空间,没有就阻塞
  17. buffer[i % BufferSize] = "ACGT"[( int)qrand() % 4];
  18. usedBytes.release(); //已用空间增加一个,有货啦!
  19. }
  20. }
  21. class Consumer : public QThread
  22. {
  23. public:
  24. void run();
  25. };
  26. void Consumer::run()
  27. {
  28. for ( int i = 0; i < DataSize; ++i) {
  29. usedBytes.acquire();
  30. fprintf( stderr, "%c", buffer[i % BufferSize]);
  31. freeBytes.release();
  32. }
  33. fprintf( stderr, "\n");
  34. }
  35. int main(int argc, char *argv[])
  36. {
  37. QCoreApplication app(argc, argv);
  38. Producer producer;
  39. Consumer consumer;
  40. producer.start();
  41. consumer.start();
  42. producer.wait();
  43. consumer.wait();
  44. return 0;
  45. }


以上是一对一的模式,一般来说,生产者多于消费者或者消费者多于生产者的情况很常见(消费者为复数或者生产者为复数什么的也很常见的),接下来提供一个复数生产者单数消费者的例子吧~

==============================================

以下是SemaphoresThread 的描述


 
 
  1. /// \author qyvlik
  2. /// \abstract
  3. /// \version 0.0.1
  4. /// \date 2015/03/08
  5. ///
  6. #ifndef SEMAPHORESTHREAD_H
  7. #define SEMAPHORESTHREAD_H
  8. #include <QObject>
  9. #include <QSemaphore>
  10. #include <QList>
  11. #include <QThread>
  12. print data to the console ///
  13. #include <QDebug>
  14. #include <stdio.h>
  15. print data to the console ///
  16. class SemaphoresThread : public QThread
  17. {
  18. Q_OBJECT
  19. public:
  20. explicit SemaphoresThread(QObject *parent = 0);
  21. ~SemaphoresThread();
  22. protected:
  23. static const int BufferSize; // 总的可被生产者使用的空间大小
  24. static const int DataSize; //
  25. static QSemaphore freeBytes; // 全局静态对象,在生产者中,用于累减可用来生成的资源的空间大小 ; 在消费者中,被累加.
  26. static QSemaphore usedBytes; // 全局静态对象,在生产者中,用于累加可用来生成的资源的空间大小 ; 在消费者中,被累减.
  27. static QList< int> data; // 全局静态数据对象
  28. virtual void run() = 0;
  29. };
  30. #endif // SEMAPHORESTHREAD_H
    static const int BufferSize;    // 总的可被生产者使用的空间大小
    static const int DataSize;      //
    static QSemaphore freeBytes;    // 全局静态对象,在生产者中,用于累减可用来生成的资源的空间大小 ; 在消费者中,被累加.
    static QSemaphore usedBytes;    // 全局静态对象,在生产者中,用于累加可用来生成的资源的空间大小 ; 在消费者中,被累减.
    static QList<int> data;         // 全局静态数据对象

====================================
我们的Producer类继承自SemaphoresThread 


 
 
  1. #ifndef PRODUCER_H
  2. #define PRODUCER_H
  3. #include "SemaphoresThread.h"
  4. #include <QMutex>
  5. class Producer : public SemaphoresThread
  6. {
  7. Q_OBJECT
  8. public:
  9. explicit Producer(QObject *parent = 0);
  10. ~Producer();
  11. protected:
  12. void run();
  13. // static function to operator ProducerCount //
  14. static void addProducer();
  15. static void removeProducer();
  16. static int producerCount();
  17. private:
  18. static int ProducerCount;
  19. static QMutex mutex;
  20. };
  21. #endif // PRODUCER_H

增加了两个静态对象,用于记录Producer构造的次数与构造的个数

通过构造的个数来计算每个Producer 对象的工作量


 
 
  1. / 生产者 //
  2. /// \brief Producer::run
  3. /// 通过 Producer::DataSize / Producer::producerCount() 得知每个生产者的工作量
  4. /// 如果 Producer::producerCount() % Producer::DataSize != 0 ;将会发生运行错误!
  5. void Producer::run()
  6. {
  7. for ( int i = 0; i < Producer::DataSize / Producer::producerCount(); ++i) {
  8. Producer::freeBytes.acquire();
  9. Producer::data.append( 1);
  10. printf( "%d",Producer::data.last());
  11. fflush( stdout);
  12. Producer::usedBytes.release();
  13. }
  14. }

===============================================

消费者,就仅仅打印数据了


 
 
  1. /// run ///
  2. /// \brief Consumer::run
  3. /// 用来消费 data 中的数据的
  4. void Consumer::run()
  5. {
  6. for ( int i = 0; i < SemaphoresThread::DataSize; ++i) {
  7. SemaphoresThread::usedBytes.acquire(); // 这个操作一次减少1个资源,如果现有资源不到1个就会阻塞
  8. printf( "%d",Consumer::data.at(i)+ 1);
  9. fflush( stdout);
  10. SemaphoresThread::freeBytes.release(); // 这个操作一次增加1个资源
  11. }
  12. }

例子下载

  •                     <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="{&quot;mod&quot;:&quot;popu_824&quot;}"><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="{&quot;mod&quot;:&quot;popu_379&quot;}" 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="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    </article>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值