参考:
Qt线程的简单使用--QReadWriteLock的用法_qt的读写锁怎么应用-CSDN博客
应用场景:多个线程同时进行读操作。
比如:100个线程进行读操作,1个线程进行写操作。
示例1:
#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();
};
#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();
}
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:修改部分代码:
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的使用
void Read_thread::run()
{QReadLocker locker(&lock);for(int i=0;i<5;i++){this->msleep(10);qDebug()<<"Read_thread:"<<QThread::currentThreadId()<<" "<<counter;}
}
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()了。