Qt多线程——QSemaphore

1.什么是信号量(Semaphore)

信号量可以理解是对于 互斥量(Mutex) 功能的拓展,互斥量只能锁定一次而信号量可以获取多次,信号量可以用来保护一定数量的同种资源。信号量最典型的应用就是 生产者消费者模型

生产者/消费者模型中对于同步的需求有两处:

  • 如果生产者过快的生产数据,将会覆盖消费者还没来得及读取的数据;
  • 如果消费者过快的消费数据,将会越过生产者并且消费到一些已经过期的数据;

针对以上的两个问题,有两种解决方案:

  • 首先让生产者生产数据填满这个缓冲区,然后等待消费者消费整个缓冲区的数据,这是一种比较笨的方法,不推荐;
  • 让生产者 和 消费者线程同时分别操作缓冲区的不同部分,这是一种比较高效的方法,推荐使用;

2.实现一个简单的生产者/消费者模型

创建 Qt控制台项目。

(1) 头文件、缓冲区、信号量。

#include <QCoreApplication>
#include <QSemaphore>
#include <QThread>
#include <stdio.h>

const int DataSize = 10000;
const int bufferSize = 100;

int buffer[bufferSize];

//生产者可生产的缓冲区部分,初始为可以生产 bufferSize
QSemaphore freeBytes(bufferSize);

//消费者可读取的缓冲区部分,初始为可以读取 0
QSemaphore usedBytes(0);

(2) 生产者线程,继承自 QThread类。

//生产者线程
class Producer : public QThread{
public:
     Producer();
     void run() override;
};

Producer::Producer(){}

void Producer::run(){
    for(int i = 0;i < DataSize;i++){
        //生产者先获取一个空闲单元,准备生产数据,如果此时缓冲区被生产者的生产的数据填满
        //消费者还没读取,那么生产者线程就阻塞
        freeBytes.acquire();
        buffer[i % bufferSize] = (i % bufferSize);

        //将消费者可以读取的资源 +1
        usedBytes.release();
    }
}

(3) 消费者线程,继承自 QThread类。

//消费者线程
class Consumer : public QThread{
public:
     Consumer();
     void run() override;
};

Consumer::Consumer(){}

void Consumer::run(){
    for(int i = 0;i < DataSize;i++){
        //生产者先获取一个空闲单元,准备读取数据,如果此时缓冲区还没有数据,消费者线程就先阻塞
        usedBytes.acquire();
        fprintf(stderr,"%d",buffer[i % bufferSize]);

        if(i % 16 == 0 && i != 0) fprintf(stderr,"\n");

        //使这个单元变得空闲,以便生产者下次生产数据填充
        freeBytes.release();
    }
}

(4) 启动生产者 和 消费者,执行完任务之后退出。

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Producer producer;
    Consumer consumer;

    //启动 生产者和消费者线程
    producer.start();
    consumer.start();

    //消费者 和 生产者线程执行完任务之后,自动退出
    producer.wait();
    consumer.wait();

    return a.exec();
}

3.运行结果

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值