详细讲解 QMutex 线程锁和 QMutexLocker 自动锁的区别
下面我们详细拆解 Qt 中用于线程同步的两个核心类:QMutex 和 QMutexLocker。
🧱 一、什么是 QMutex?
QMutex 是 Qt 中的互斥锁(mutex)类,用于防止多个线程同时访问共享资源。
✅ 使用场景:
多个线程同时访问一个变量或数据结构,可能引发数据竞争(data race);
我们需要保证某一段代码在任意时刻只能被一个线程执行(临界区)。
🧪 示例:使用 QMutex 实现线程安全
QMutex mutex;
int counter = 0;
void threadSafeFunction() {
mutex.lock(); // 加锁
counter++; // 临界区:只能有一个线程同时运行这里
mutex.unlock(); // 解锁
}
⚠️ 问题:手动 lock/unlock 容易出错!
如果中间代码 throw 出异常,或者你忘记调用 unlock(),程序就会死锁(锁永远不释放)。
🧰 二、QMutexLocker 是什么?
QMutexLocker 是 Qt 提供的一个RAII(资源自动管理)类,用于自动加锁和解锁。
✅ 特点:
构造函数自动调用 mutex.lock();
析构函数自动调用 mutex.unlock();
避免手动管理锁,保证锁一定会释放(即使中途抛异常)。
🧪 示例:使用 QMutexLocker
QMutex mutex;
int counter = 0;
void threadSafeFunction() {
QMutexLocker locker(&mutex); // 自动加锁
counter++; // 临界区
} // 自动解锁(出了作用域 locker 被析构)
✅ 使用对比总结
✍️ 示例场景:线程安全的缓存操作
class SafeCache {
public:
void insert(int key, QString value) {
QMutexLocker locker(&mutex); // 自动加锁
cache.insert(key, value);
}
QString get(int key) {
QMutexLocker locker(&mutex); // 自动加锁
return cache.value(key);
}
private:
QMutex mutex;
QMap<int, QString> cache;
};
📦 进阶提示:
如果你在某个类中频繁访问锁,可以考虑使用 QReadWriteLock 区分读写锁;
QMutex 也支持 tryLock(),可以避免阻塞线程:
if (mutex.tryLock()) {
// do something
mutex.unlock();
}
🧠 总结一句话:
QMutex 是线程同步的低层工具,QMutexLocker 是安全易用的高级封装,两者结合使用,可以轻松保障多线程 Qt 应用的线程安全。