一.概述
1.在Qt中,主要有以下几种锁的类型:
(1)QMutex(互斥锁):是最常见的锁类型,用于实现简单的互斥访问。可以通过lock()和unlock()手动控制锁的加锁和解锁。
(2)QMutexLocker:是一个RAII类,用于简化对QMutex的加锁和解锁过程。在创建QMutexLocker对象时,会自动加锁,离开作用域时会自动解锁,确保资源在合适的时候被解锁,避免忘记解锁或异常导致未解锁的情况。
(3)QReadWriteLock(读写锁):用于实现读写分离的锁机制,允许多个线程同时读取共享资源,但只有一个线程可以进行写入操作。可以通过lockForRead()和lockForWrite()手动控制读取锁和写入锁。
QReadLocker和QWriteLocker:是QReadWriteLock的RAII类,用于简化对QReadWriteLock的加读锁和加写锁过程。在创建QReadLocker或QWriteLocker对象时,会自动加读锁或加写锁,离开作用域时会自动解锁,确保资源在合适的时候被解锁。
(4)QSemaphore(信号量):允许控制对共享资源的并发访问数量。可以通过acquire()和release()手动控制资源的获取和释放。
(5)QWaitCondition(条件变量):用于线程间的等待和唤醒,允许一个线程等待特定条件的发生,并在其他线程满足条件时发出信号。
总体来说,Qt提供了丰富的锁机制来帮助开发者实现线程安全的并发编程。选择合适的锁类型取决于具体的并发场景和资源访问需求。在使用锁时,一定要小心避免死锁和竞态条件等问题,确保线程间安全的共享资源访问。
同时,使用RAII类(如QMutexLocker、QReadLocker、QWriteLocker)可以简化锁的管理,减少出错的可能性。
2.其他线程同步机制
QThread::wait()
QThread::wait() 是Qt提供的一个线程同步机制,可以用于等待一个线程完成执行。调用该函数会使当前线程阻塞,直到指定的线程完成执行为止。
二.代码示例
1.QMutex(互斥锁)的例子:
#include <QMutex>
QMutex mutex;
int count = 0;
for (int i = 0; i < 1000; ++i) {
mutex.lock();
++count;
mutex.unlock();
}
qDebug() << "Final count:" << count;
2.QMutexLocker的例子:
#include <QCoreApplication>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>
void run() {
QMutex mutex;
QMutexLocker locker(&mutex);
for (int i = 0; i < 1000; ++i) {
++sharedResource;
}
qDebug() << "Thread" << QThread::currentThreadId() << "finished. Current count:" << sharedResource;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
run();
return a.exec();
}
3.QReadWriteLock(读写锁)的例子:
#include <QCoreApplication>
#include <QReadWriteLock>
#include <QDebug>
#include <QThread>
#include <QMutexLocker>
#include <QRandomGenerator>
// 假设的共享资源
class SharedData {
public:
SharedData() : data(0) {}
void read() const {
// 读取操作,这里只是打印信息
qDebug() << "Thread" << QThread::currentThreadId() << "is reading the data:" << data;
}
void write(int newValue) {
// 写入操作,这里设置新值并打印信息
data = newValue;
qDebug() << "Thread" << QThread::currentThreadId() << "wrote the data:" << data;
}
int data;
};
// 全局的共享数据和读写锁
SharedData sharedData;
QReadWriteLock rwLock;
void readTask() {
// 使用 QReadLocker 自动管理读锁
QReadLocker locker(&rwLock);
sharedData.read();
}
void writeTask(int value) {
// 使用 QWriteLocker 自动管理写锁
QWriteLocker locker(&rwLock);
sharedData.write(value);
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// 创建并启动读取线程
QThread readThread;
QObject::connect(&readThread, &QThread::started, readTask);
readThread.start();
// 等待读取线程开始
readThread.sleep(1); // 示例中简单等待,实际应用中可能需要更复杂的同步机制
// 在主线程中执行写入任务
writeTask(27);
// 等待读取线程完成
readThread.wait();
return a.exec();
}
4.QSemaphore(信号量)的例子:
#include <QCoreApplication>
#include <QSemaphore>
#include <QDebug>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSemaphore semaphore(1); // 初始信号量计数为1
// 创建两个线程,模拟同时访问共享资源
QThread thread1, thread2;
QObject::connect(&thread1, &QThread::started, [&]() {
semaphore.acquire();
qDebug() << "Thread 1: Accessing shared resource...";
QThread::sleep(2); // 模拟资源访问
semaphore.release();
qDebug() << "Thread 1: Done!";
});
QObject::connect(&thread2, &QThread::started, [&]() {
semaphore.acquire();
qDebug() << "Thread 2: Accessing shared resource...";
QThread::sleep(2); // 模拟资源访问
semaphore.release();
qDebug() << "Thread 2: Done!";
});
thread1.start();
thread2.start();
thread1.wait();
thread2.wait();
return a.exec();
}
5.QWaitCondition(条件变量)的例子:
#include <QCoreApplication>
#include <QMutex>
#include <QWaitCondition>
#include <QDebug>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QMutex mutex;
QWaitCondition condition;
bool isReady = false;
// 等待线程
QThread waitThread;
QObject::connect(&waitThread, &QThread::started, [&]() {
QMutexLocker locker(&mutex);
qDebug() << "Waiting thread: Waiting for condition...";
condition.wait(&mutex);
qDebug() << "Waiting thread: Condition signaled!";
});
// 发送信号线程
QThread signalThread;
QObject::connect(&signalThread, &QThread::started, [&]() {
QThread::sleep(2);
QMutexLocker locker(&mutex);
isReady = true;
qDebug() << "Signaling thread: Condition is ready!";
condition.wakeOne();
});
waitThread.start();
signalThread.start();
waitThread.wait();
signalThread.wait();
return a.exec();
}
三.其他线程同步机制
1.QThread::wait()
QThread::wait() 是Qt提供的一个线程同步机制,可以用于等待一个线程完成执行。调用该函数会使当前线程阻塞,直到指定的线程完成执行为止。
以下是一个使用QThread::wait()的示例:
#include <QThread>
#include <QDebug>
class Thread : public QThread
{
public:
void run() override
{
qDebug() << "Thread started";
sleep(1);
qDebug() << "Thread finished";
}
};
int main(int argc, char *argv[])
{
Thread thread;
thread.start();
qDebug() << "Waiting for thread to finish...";
thread.wait();
qDebug() << "Thread finished, exiting...";
}
在这个示例中,我们创建了一个Thread线程,并调用start()函数启动它。然后,我们调用QThread::wait()函数等待该线程完成执行。该函数会使当前线程阻塞,直到指定的线程完成执行为止。