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 就沒有必要。

相关推荐
谢亮_vipxieliang26 分钟前
Stream API 不是银弹:常见坑与性能建议
java·开发语言
迅猛龙办公室38 分钟前
实现第一个python程序(HelloWorld)
开发语言·python
phltxy41 分钟前
C 语言动态内存管理:从申请空间到安全释放
c语言·开发语言·ui
可乐鸡翅yeah_1 小时前
M3U8 防盗链 URL‑Token 签名,新手开发实操避坑
开发语言·javascript·ios·音视频·safari
2603_965896621 小时前
JS原型与原型链|对象继承与实例底层原理
开发语言·javascript·原型模式
拉格朗日(Lagrange)1 小时前
【第2 章】WorkBuddy 从入门到高手
开发语言·python
yujunl1 小时前
在U9C订单列表上开放多个按钮层叠的问题解决
开发语言
喆星时瑜1 小时前
Win10/11 安装 R 与 RStudio 详细图文教程
开发语言·r语言·安装
心中有你02142 小时前
【路径规划】A*寻路算法最通俗易懂讲解(C语言完整实现+详细注释)
c语言·开发语言·算法
言乐62 小时前
Python自动去除水印
开发语言·python·django·virtualenv·pygame