Qt中的读写锁

t中的QReadWriteLock类为我们提供了读写锁的功能。读写锁是用来保护可以被读访问和写访问的资源的一种同步工具。如果你想让多个线程同时的对资源进行读访问,但只要有一个线程要对资源进行写访问时,所有其他的线程必须等待,直到写访问完成。对于这种情况,读写锁是非常有用的。

读写锁的使用也非常简单,如下例子代码所示:

[cpp]  view plain  copy
 print ?
  1. QReadWriteLock lock;  
  2.   
  3. void ReaderThread::run()  
  4. {  
  5.     ...  
  6.     lock.lockForRead();  
  7.     read_file();  
  8.     lock.unlock();  
  9.     ...  
  10. }  
  11.   
  12. void WriterThread::run()  
  13. {  
  14.     ...  
  15.     lock.lockForWrite();  
  16.     write_file();  
  17.     lock.unlock();  
  18.     ...  
  19. }  

同时,为了确保写操作不会被读操作永远阻塞,当有等待中的写操作时,请求读操作会被阻塞,即使当前的锁由另一个读操作持有。同样,当锁被一个写操作持有时,另一个写操作进来了,那么写操作将会优先于读操作获得锁。

和QMutex一样,QReadWriteLock也可以被同一个线程递归的锁定,只要在构造函数中传入一个QReadWriteLock::Recursive标志。在这种情况下,unlock()被调用的次数必须和lockForWrite()或lockForRead()被调用的次数一样多。但要注意,在一个线程中,递归锁定的类型不能改变,即不能先以读操作上锁,又要以写操作上锁。

同样,为了方便使用QReadWriteLock,Qt还提供了QReadLocker和QWriteLocker两个方便类。能使我们更方便的使用读写锁的功能。即我们可以使用下面这种方式来使用读写锁的功能:

[cpp]  view plain  copy
 print ?
  1. QReadWriteLock lock;  
  2.   
  3. QByteArray readData()  
  4. {  
  5.     QReadLocker locker(&lock);  
  6.     read_file();  
  7. }  
  8.   
  9. void writeData(const QByteArray &data)  
  10. {  
  11.     QWriteLocker locker(&lock);  
  12.     write_file();  
  13. }  


下面我们写一个例子,来使用以下QReadWriteLock。

新建一个Qt控制台程序。在main.cpp中,定义共享数据和读写锁。代码如下:

[cpp]  view plain  copy
 print ?
  1. #include <QCoreApplication>  
  2. #include <QReadWriteLock>  
  3. #include "readthread.h"  
  4. #include "writethread.h"  
  5.   
  6. int scores[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};  
  7. QReadWriteLock rwLock;  
  8.   
  9. int main(int argc, char *argv[])  
  10. {  
  11.     QCoreApplication a(argc, argv);  
  12.   
  13.     ReadThread readThread[10];  
  14.     WriteThread writeThread;  
  15.   
  16.     for(int i = 0; i < 10; i++)  
  17.         readThread[i].start();  
  18.     writeThread.start();  
  19.   
  20.     for(int i = 0; i < 10; i++)  
  21.         readThread[i].wait();  
  22.     writeThread.wait();  
  23.   
  24.     return a.exec();  
  25. }  
此处,我们启动了10个读线程,一个写线程,来模拟多个读者,一个写者的情况。

下面,新建出这两个线程,使用QThread类。

其中,读线程的run()函数实现如下:

[cpp]  view plain  copy
 print ?
  1. extern int scores[10];  
  2. extern QReadWriteLock rwLock;  
  3. void ReadThread::run()  
  4. {  
  5.     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));  
  6.     while(true)  
  7.     {  
  8.         rwLock.lockForRead();  
  9.         qDebug() << scores[rand() % 10];  
  10.         rwLock.unlock();  
  11.     }  
  12. }  

读操作,是不断的从数组中随机的读取数据。


写线程的run()函数实现如下:

[cpp]  view plain  copy
 print ?
  1. extern int scores[10];  
  2. extern QReadWriteLock rwLock;  
  3. void WriteThread::run()  
  4. {  
  5.     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));  
  6.     while(true)  
  7.     {  
  8.         rwLock.lockForWrite();  
  9.         scores[rand() % 10] = rand();  
  10.         rwLock.unlock();  
  11.         sleep(1); //写线程睡眠1s  
  12.     }  
  13. }  
写操作,在数组中随机的写入一个随机数。然后睡眠1秒。

运行结果如下,大家也可以自行测试



  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
QReadWriteLock是Qt提供的实现类,它可以提高多线程程序的效率。下面是一个QReadWriteLock的示例: ```c++ #include <QCoreApplication> #include <QReadWriteLock> #include <QThread> #include <QDebug> QReadWriteLock rwLock; // 创建 int data = 0; // 共享数据 void readData() // 线程 { while (true) { rwLock.lockForRead(); // 获取 qDebug() << "Read data:" << data; rwLock.unlock(); // 释放 QThread::msleep(500); } } void writeData() // 线程 { while (true) { rwLock.lockForWrite(); // 获取 data++; // 修改共享数据 qDebug() << "Write data:" << data; rwLock.unlock(); // 释放 QThread::msleep(1000); } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建两个线程和一个线程 QThread thread1, thread2, thread3; QObject::connect(&thread1, &QThread::started, readData); QObject::connect(&thread2, &QThread::started, readData); QObject::connect(&thread3, &QThread::started, writeData); thread1.start(); thread2.start(); thread3.start(); return a.exec(); } ``` 在这个示例,我们创建了一个全局的QReadWriteLock对象rwLock和一个共享变量data。同时,我们创建了两个线程和一个线程,线程不断地取共享变量data的值,线程不断地修改data的值。我们通过lockForRead()和unlock()方法获取和释放,通过lockForWrite()和unlock()方法获取和释放。这样,我们就实现了的功能,保证多个线程能够安全地访问共享数据。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值