Qt 读写锁QReadWriteLock
Qt 读写锁
QReadWriteLock
在基于互斥量QMutex的线程控制中,每次只能有一个线程获得互斥量的权限。如果在一个程序中有多个线程读取某个变量,使用互斥量时也必须排队。若只是读取一个变量,是可以让多个线程同时访问的,在这种只读的情况下,若仍然使用互斥量,就会降低程序的性能。
QReadWriteLock的特点:
- 读共享,写独占;
- 默认写锁优先级高于读锁优先级;
QReadWriteLock类的成员函数
函数名称 | 函数功能 |
---|---|
QReadWriteLock() | 构造读写锁对象 |
lockForRead() | 以只读方式锁定资源,如果有其他线程以写入方式锁定,该函数会阻塞 |
lockForWrite() | 以写入方式锁定资源,如果本线程或其他线程对读或写模式锁定资源,该函数就阻塞 |
unlock() | 解读锁或解写锁 |
tryLockForRead() | lockForRead()的非阻塞版本。尝试请求读锁,可以设置超时时间 |
tryLockForWrite() | lockForWrite()的非阻塞版本。尝试请求写锁,可以设置超时时间 |
程序示例
一个线程写值,多个线程读取值的场景
// 公共数据和读写锁
class TestData
{
public:
static int sm_nSharedNumber;
static QReadWriteLock sm_ReadWriteLock;
};
int TestData::sm_nSharedNumber = 10;
QReadWriteLock TestData::sm_ReadWriteLock;
// 读取数据的线程类
class WorkThreadA : public QThread
{
Q_OBJECT
public:
explicit WorkThreadA(QObject *parent = nullptr);
~WorkThreadA() = default;
protected:
void run() override;
};
WorkThreadA::WorkThreadA(QObject *parent) : QThread(parent)
{
}
void WorkThreadA::run()
{
TestData::sm_ReadWriteLock.lockForRead();
qDebug() << QString::fromLocal8Bit("read1 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
msleep(10);
qDebug() << QString::fromLocal8Bit("read2 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
msleep(20);
qDebug() << QString::fromLocal8Bit("read3 ----- 线程1 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
TestData::sm_ReadWriteLock.unlock();
}
// 写入数据的线程类
class WorkThreadB : public QThread
{
Q_OBJECT
public:
explicit WorkThreadB(QObject *parent = nullptr);
~WorkThreadB() = default;
protected:
void run() override;
};
WorkThreadB::WorkThreadB(QObject *parent) : QThread(parent)
{
}
void WorkThreadB::run()
{
TestData::sm_ReadWriteLock.lockForWrite();
TestData::sm_nSharedNumber += 5;
TestData::sm_nSharedNumber *= 10;
qDebug() << QString::fromLocal8Bit("write1 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
qDebug() << QString::fromLocal8Bit("write2 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
qDebug() << QString::fromLocal8Bit("write3 ----- 线程2 ID:") << QThread::currentThreadId() << "Result = " << TestData::sm_nSharedNumber;
TestData::sm_ReadWriteLock.unlock();
}
// 测试函数
void Test()
{
// 创建了三个读取数据线程的对象
unique_ptr<WorkThreadA> upThreadA1 = std::make_unique<WorkThreadA>();
unique_ptr<WorkThreadA> upThreadA2 = std::make_unique<WorkThreadA>();
unique_ptr<WorkThreadA> upThreadA3 = std::make_unique<WorkThreadA>();
// 一个写入数据线程对象
unique_ptr<WorkThreadB> upThreadB = std::make_unique<WorkThreadB>();
upThreadA1->start();
upThreadB->start();
upThreadA2->start();
upThreadA3->start();
upThreadA1->wait();
upThreadA2->wait();
upThreadA3->wait();
upThreadB->wait();
}