参考:
Qt线程的简单使用--QReadWriteLock的用法_qt的读写锁怎么应用-CSDN博客
应用场景:多个线程同时进行读操作。
比如:100个线程进行读操作,1个线程进行写操作。
示例1:
cpp
#include <QObject>
#include <QThread>
class Read_thread : public QThread
{
Q_OBJECT
public:
explicit Read_thread(QObject *parent = nullptr);
protected:
void run();
};
class Write_thread : public QThread
{
Q_OBJECT
public:
explicit Write_thread(QObject *parent = nullptr);
protected:
void run();
};
cpp
#include <QReadWriteLock>
int counter=0;
QReadWriteLock lock;
void Read_thread::run()
{
lock.lockForRead();
for(int i=0;i<5;i++)
{
this->msleep(10);
qDebug()<<"Read_thread:"<<QThread::currentThreadId()<<" "<<counter;
}
lock.unlock();
}
void Write_thread::run()
{
lock.lockForWrite();
for(int i=0;i<5;i++)
{
counter++;
this->msleep(10);
qDebug()<<"Write_thread:"<<QThread::currentThreadId()<<" "<<counter;
}
lock.unlock();
}
cpp
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
qDebug()<<"main:"<<QThread::currentThreadId();
connect(this,SIGNAL(destroyed()),this,SLOT(quitThreadSlot()));
t=new Read_thread(this);
t->start();
t1=new Read_thread(this);
t1->start();
t2=new Write_thread(this);
t2->start();
t3=new Write_thread(this);
t3->start();
}
void Widget::quitThreadSlot()
{
t1->quit();
t1->wait();
t->quit();
t->wait();
t2->quit();
t2->wait();
t3->quit();
t3->wait();
}
输出结果:
main: 0x5a08
Read_thread: 0x4f30 0
Read_thread: 0x62d8 0
Read_thread: 0x4f30 0
Read_thread: 0x62d8 0
Read_thread: 0x62d8 0
Read_thread: 0x4f30 0
Read_thread: 0x4f30 0
Read_thread: 0x62d8 0
Read_thread: 0x4f30 0
Read_thread: 0x62d8 0
Write_thread: 0x339c 1
Write_thread: 0x339c 2
Write_thread: 0x339c 3
Write_thread: 0x339c 4
Write_thread: 0x339c 5
Write_thread: 0x60b0 6
Write_thread: 0x60b0 7
Write_thread: 0x60b0 8
Write_thread: 0x60b0 9
Write_thread: 0x60b0 10
分析结果:可以看到,允许不同的线程同时读counter,这里就是在交替地读counter,
之后进行写操作,不是交替进行的,
而是先执行Write_thread: 0x339c,
再执行Write_thread: 0x60b0。
即:可以同时读,不可以同时写。
示例2:修改部分代码:
cpp
t=new Read_thread(this);
t->start();
QThread::msleep(1000);
t2=new Write_thread(this);
t2->start();
t3=new Write_thread(this);
t3->start();
t1=new Read_thread(this);
t1->start();
输出结果:
main: 0x5c84
Read_thread: 0xb60 0
Read_thread: 0xb60 0
Read_thread: 0xb60 0
Read_thread: 0xb60 0
Read_thread: 0xb60 0
Write_thread: 0x3aa0 1
Write_thread: 0x3aa0 2
Write_thread: 0x3aa0 3
Write_thread: 0x3aa0 4
Write_thread: 0x3aa0 5
Write_thread: 0x4788 6
Write_thread: 0x4788 7
Write_thread: 0x4788 8
Write_thread: 0x4788 9
Write_thread: 0x4788 10
Read_thread: 0x38b0 10
Read_thread: 0x38b0 10
Read_thread: 0x38b0 10
Read_thread: 0x38b0 10
Read_thread: 0x38b0 10
分析:Read_thread: 0xb60先进行读操作主线程阻塞1s
Write_thread: 0x3aa0进行写操作
Write_thread:0x4788进行写操作
Read_thread: 0x38b0进行读操作
示例3:QReadLocker和QWriteLocker的使用
cpp
void Read_thread::run()
{
QReadLocker locker(&lock);
for(int i=0;i<5;i++)
{
this->msleep(10);
qDebug()<<"Read_thread:"<<QThread::currentThreadId()<<" "<<counter;
}
}
cpp
void Write_thread::run()
{
QWriteLocker locker(&lock);
for(int i=0;i<5;i++)
{
counter++;
this->msleep(10);
qDebug()<<"Write_thread:"<<QThread::currentThreadId()<<" "<<counter;
}
}
这样写只是更简单了一些,不需要再locked(),unlocked()了。