QWaitCondition和QMutex详细介绍

一.概念

QWaitCondition 和 QMutex 是 Qt 框架中用于实现多线程同步的重要类。它们通常一同使用,以确保在多线程环境中对共享资源的安全访问。下面是这两个类的详细介绍及示例代码。

  1. QMutex(互斥量)

定义:

QMutex 是一个互斥量,用于保护对共享资源的访问,确保在同一时间只有一个线程可以访问该资源。使用 QMutex 可以避免因为多个线程同时修改同一数据而导致的数据不一致性问题。

常用功能:

  • lock():加锁,阻塞其他尝试获取同一锁的线程。
  • unlock():解锁,允许其他线程获取该锁。
  • tryLock():尝试加锁,如果无法立即获取锁则返回 false。
  1. QWaitCondition(条件变量)

定义:

QWaitCondition 是一个条件变量,用于在特定条件未满足时,使线程进入等待状态。当条件满足时,可以唤醒处于等待状态的线程。

常用功能:

  • wait(QMutex *mutex):等待条件满足,释放指定的互斥量以允许其他线程访问共享资源。
  • wakeOne():唤醒一个等待的线程。
  • wakeAll():唤醒所有等待的线程。

二.示例代码

下面是一个使用 QMutex 和 QWaitCondition 的简单示例,演示如何安全地在多个线程之间进行同步。

cpp 复制代码
#include <QCoreApplication>  
#include <QThread>  
#include <QMutex>  
#include <QWaitCondition>  
#include <QDebug>  

class WorkerThread : public QThread {  
    Q_OBJECT  

public:  
    WorkerThread() : conditionMet(false) {}  

    void run() override {  
        qDebug() << "Worker thread starting...";  
        QMutexLocker locker(&mutex);  // Lock the mutex  

        // Wait until the condition is met  
        while (!conditionMet) {  
            qDebug() << "Worker thread waiting...";  
            condition.wait(&mutex);  // Wait for the condition to change  
        }  

        // If the condition is met, do some work  
        qDebug() << "Worker thread running...";  
        // Simulate work  
        QThread::sleep(2);  
        qDebug() << "Worker thread finished.";  
    }  

    void setConditionMet() {  
        QMutexLocker locker(&mutex);  // Lock the mutex  
        conditionMet = true;          // Change the condition  
        condition.wakeOne();          // Wake one waiting thread  
    }  

private:  
    QMutex mutex;                   // Mutex for synchronization  
    QWaitCondition condition;       // Condition variable  
    bool conditionMet;             // Condition to be met  
};  

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

    WorkerThread workerThread;  
    workerThread.start();  // Start the worker thread  

    // Simulate some delay before setting the condition  
    QThread::sleep(1);  
    workerThread.setConditionMet();  // Notify the worker thread  

    workerThread.wait();  // Wait for the worker thread to finish  
    return a.exec();  
}  

三.代码解释

  1. WorkerThread 类: 这个类继承自 QThread,并实现了 run() 方法。在 run() 方法中,线程会等待条件变量。

  2. 条件控制:

  • 在 run() 方法中,使用 wait() 方法进入等待状态,并释放互斥量 mutex,以允许其他线程访问共享资源。
  • 当 setConditionMet() 被调用时,它会锁定互斥量,设置 conditionMet 为 true,并调用 wakeOne() 唤醒一个等待的线程。
  1. 主函数:
  • 在主函数中,创建并启动 WorkerThread 实例。
  • 通过 setConditionMet() 方法,在主线程中修改状态,唤醒工作线程。

总结

通过使用 QMutex 和 QWaitCondition,你可以有效地管理多线程中的共享资源访问和条件同步。在实际应用中,这种组合非常强大,可以避免数据竞争和确保线程间的有效沟通。

四.mutable关键字

在 C++ 中,mutable 关键字的目的是允许在 const 成员函数中修改该对象的成员变量。因此,mutable 用于修饰成员变量,在某些情况下是有意义的,尤其是当你想在 const 成员函数中修改某个变量时。

对于 mutable QMutex mutex_;

  1. 用途:
  • 如果你将 mutex_ 声明为 mutable,那么你可以在类的 const 成员函数中对这个互斥量进行加锁和解锁。这样,如果这个类的实例是 const 类型的,但你仍然需要对某些内部状态进行保护(比如状态变量),你就可以使用这个 mutable 的 QMutex。
  1. 例子:
cpp 复制代码
class MyClass {  
public:  
    void doSomething() const {  
        QMutexLocker locker(&mutex_); // 在 const 方法中加锁  
        // 修改其他成员变量或访问共享资源  
    }  

private:  
    mutable QMutex mutex_; // 允许在 const 方法中使用  
    int sharedResource_;  
};  

是否多余?

不多余:

  • 如果给定类会有 const 成员函数,并且那些函数需要锁定 mutex_ 以访问或修改共享状态,那么将 mutex_ 声明为 mutable 是合适的。

多余:

  • 如果类的成员函数不需要被声明为 const,或 mutex_ 的主要作用并不需要在 const 函数中锁定,那么 mutable 就可以认为是不必要的。

结论

总结来说,究竟将 QMutex 声明为 mutable 是否多余,取决于你的类的设计和需求。如果存在 const 成员函数并需要使用互斥量保护共享资源,则使用 mutable 是合理的。如果没有这样的需求,仅仅加锁或解锁的操作在非常规的成员函数中使用,那么 mutable 就沒有必要。

相关推荐
铁打的阿秀8 分钟前
okhttp 报java.lang.IllegalStateException: closed
java·开发语言·okhttp
Zhen (Evan) Wang14 分钟前
What is new in C# 7,8,9,10
开发语言·c#
有杨既安然24 分钟前
Python数据分析与可视化基础教程
开发语言·python·信息可视化·数据分析·excel
van叶~25 分钟前
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——12.二叉树(习题)
开发语言·c++·算法
`北极星33 分钟前
应用程序已被 Java 安全阻止:Java 安全中的添加的例外站点如何对所有用户生效
java·开发语言·安全
蒙娜丽宁35 分钟前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
会敲代码的小张36 分钟前
设计模式-外观模式
java·开发语言·后端·设计模式·外观模式
爱里承欢。1 小时前
【python - 函数】
开发语言·python
一只邪恶大泡2 小时前
为什么HTTPS会引入SSL/TLS协议
开发语言·数据结构·数据库·sql·mysql