在Qt中实现线程互斥主要有以下几种方式,每种方式适用于不同的场景:
1. 互斥锁(QMutex)
- 核心机制:通过
QMutex类提供互斥访问控制,确保同一时间仅一个线程访问共享资源。 - 使用方法:
QMutex mutex; mutex.lock(); // 手动加锁 // 访问共享资源 mutex.unlock(); // 手动解锁 - 增强工具:
QMutexLocker(RAII封装)- 优势:自动管理锁的获取与释放,避免死锁。
QMutex mutex; { QMutexLocker locker(&mutex); // 构造时加锁,析构时自动解锁 // 访问共享资源 } // 此处自动解锁
2. 读写锁(QReadWriteLock)
- 适用场景:读多写少场景,允许多线程并发读,但写操作独占。
- 实现方式:
- 读锁:
QReadLocker - 写锁:
QWriteLocker
QMutex mutex; { QMutexLocker locker(&mutex); // 构造时加锁,析构时自动解锁 // 访问共享资源 } // 此处自动解锁 - 读锁:
3. 信号量(QSemaphore)
- 用途:控制并发访问资源的线程数量(如生产者-消费者模型)。
- 示例:限制同时访问资源的线程数为2
QMutex mutex; { QMutexLocker locker(&mutex); // 构造时加锁,析构时自动解锁 // 访问共享资源 } // 此处自动解锁
4. 条件变量(QWaitCondition)
- 作用:线程间同步,实现“等待-通知”机制。
- 典型模式:
QMutex mutex; QWaitCondition condition; // 等待线程 mutex.lock(); while (!conditionMet) { condition.wait(&mutex); // 释放锁并等待,唤醒后重新获取锁 } mutex.unlock(); // 通知线程 mutex.lock(); conditionMet = true; condition.wakeAll(); // 唤醒所有等待线程 mutex.unlock();
5. 信号槽机制(线程安全队列)
- 默认行为:跨线程信号自动通过事件队列传递(
QueuedConnection),确保槽函数在目标线程执行。 - 优势:无需手动加锁,天然线程安全。
// 发射信号(自动加入接收者线程队列) emit dataReady(sharedData); // 槽函数在接收者线程执行 void Receiver::handleData(const Data& data) { /* 安全访问 */ }
6. 其他辅助方法
- QThread::wait():等待线程结束,用于简单同步。
- QMetaObject::invokeMethod():跨线程调用方法,支持同步/异步。
// 异步调用(默认) QMetaObject::invokeMethod(obj, "methodName", Qt::QueuedConnection); // 同步调用(阻塞当前线程) QMetaObject::invokeMethod(obj, "methodName", Qt::BlockingQueuedConnection);
选择策略
| 方式 | 适用场景 | 性能 | 复杂度 |
|---|---|---|---|
| QMutex | 简单互斥访问 | 高 | 低 |
| QReadWriteLock | 读多写少的共享数据 | 中 | 中 |
| QSemaphore | 资源池或生产者-消费者模型 | 中 | 中 |
| QWaitCondition | 复杂条件同步(如任务队列) | 低 | 高 |
| 信号槽 | 跨线程通信或事件驱动 | 高 | 低 |
最佳实践:优先使用信号槽或QMutexLocker简化代码,复杂场景结合条件变量与信号量。避免嵌套锁和死锁风险,确保所有锁操作成对出现。
183

被折叠的 条评论
为什么被折叠?



