qt-同步线程

同步线程概述:

Qt中的QMutex、QReadWriteLock、QSemaphore和QWaitCondition类提供了同步线程的方法。虽然使用线程的思想是多个线程可以尽可能地并发执行,但是总有一些时刻,一些线程必须停止来等待其他线程。例如,如果两个线程尝试同时访问相同的全局变量,则结果通常是不确定的。

  • QMutex
    QMutex提供了一个互斥锁(mutex),在任何时间至多有一个线程可以获得mutex。如果一个线程尝试获得mutex,而此时mutex已经被锁住了,则这个线程将会睡眠,直到现在获得mutex的线程对mutex进行解锁为止。互斥锁经常用于对共享数据的访问进行保护。(例如,可以同时被多个线程访问的数据)
  • QReadWriteLock
    QReadWriteLock即读-写锁,与QMutex很相似,只不过它将对共享数据的访问区分为“读”访问和“写”访问,允许多个线程同时对数据进行“读”访问。在可能的情况下使用QReadWriteLock代替QMutex,可以提高多线程程序的并发速度。
  • QSemaphore
    QSemaphore即信号量,是QMutex的一般化,它用来保护一定数量的相同的资源,而互斥锁mutex只能保护一个资源。QSemaphore有个经典的例子,即生产者消费者,后面将会以此例子进行演示同步线程的效果。
  • QWaitCondition
    QWaitCondition即条件变量,允许一个线程在一些条件满足时唤醒其他的线程。一个或多个线程可以被阻塞来等待一个QWaitCondition,从而设置一个用于wakeOne()或者wakeAll()的条件。使用wakeOne()可以唤醒一个随机选取的等待线程,而使用wakeAll()可以唤醒所有正在等待的线程。
  • 生产者消费者示例(采取信号量)
    演示代码:
//MyThread.h --- Producer and Consumer Thread 
#include <QtCore>
#include <stdio.h>
#include <stdlib.h>
#include <QDebug>

#include <QThread>

//生产者线程
class Producer : public QThread
{
   Q_OBJECT
public:
   explicit Producer(QObject *parent = nullptr);
protected:
   void run(); //重写run方法
};

//消费者线程
class Consumer : public QThread
{
   Q_OBJECT
public:
   explicit Consumer(QObject *parent = nullptr);
protected:
   void run();
};
//MyThread.cpp
#include "producer.h"

//下面是全局变量,给生产者和消费者共同访问
const int DataSize = 10;  //生产者总的生产数
const int BufferSize = 5; //缓冲区的大小
char buffer[BufferSize];
QSemaphore freeBytes(BufferSize); //空闲区域信号量
QSemaphore usedBytes; //已使用区域的信号量


Producer::Producer(QObject *parent)
    : QThread{parent}
{
}

void Producer::run()
{
    for(int i= 0; i<DataSize; ++i){
        freeBytes.acquire(); //获取一个空闲区域的资源
        buffer[i%BufferSize] = "ACGT"[(int) rand()%4]; //随机返回ACGT中的任何一个字符
        qDebug() << QString("producer: %1").arg(buffer[i%BufferSize]);
        usedBytes.release(); //释放一个使用区域的资源
//        QThread::msleep(500);
    }
}

Consumer::Consumer(QObject *parent)
    : QThread{parent}
{
}

void Consumer::run()
{
   for(int i = 0; i<DataSize; ++i){
       usedBytes.acquire(); //获取一个使用区域的资源
       qDebug() << QString("consumer: %1").arg(buffer[i%BufferSize]);
       freeBytes.release(); //释放一个空闲区域的资源
   }
}
//main.cpp
#include <QCoreApplication>
#include "producer.h"

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();
}

演示效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值