当前位置: 首页 > news >正文

QT 读写锁

一、概述

1、读写锁是一种线程同步机制,用于解决多线程环境下的读写竞争问题。

2、读写锁允许多个线程同时获取读锁(共享访问),但只允许一个线程获取写锁(独占访问)。

3、这种机制可以提高并发性能,因为多个线程可以同时读取共享资源而不会相互干扰。

4、当一个线程有写锁时,其它线程的读锁和写锁请求会被阻塞,直到写锁被释放。

5、QReadWriteLock是Qt框架提供用于线程同步的类,它是一个读写锁(Read-Write Lock)。读写锁允许多个线程同时进行读操作,但在写操作时需要独占访问。

二、使用方法

1、使用写锁

QReadWriteLock lock;

//方式一:
lock.lockForWrite();
//这里修改共享资源
lock.unlock();

//方式二:
QWriteLocker locker(&lock);
//这里修改共享资源

 2、使用读锁

QReadWriteLock lock;

//方式一:
lock.lockForRead();
//这里读取共享资源
lock.unlock();

//方式二:
QReadLocker locker(&lock);
//这里读取共享资源

三、 QReadWriteLock::RecursionMode

1、Recursive:递归模式,一个线程可以多次锁定同一个读写锁,并且在进行相应数量的unlock()调用之前读写锁不会被解锁。

QReadWriteLock m_lock{ QReadWriteLock::Recursive };

2、NonRecursive:非递归模式,默认值。一个线程只能锁定一个读写锁一次。

QReadWriteLock m_lock{ QReadWriteLock::NonRecursive };

四、常用成员函数 

1、void lockForRead()

获取读锁,如果没有其它线程持有写锁,则能够立即获取读锁。如果有其它线程持有写锁,则当前线程会被阻塞,直到写锁被释放。

2、void lockForWrite()

获取写锁,如果没有其它线程持有读锁或写锁,则能狗立即获取写锁。如果有其它线程持有写锁或读锁,则当前线程会被阻塞,直到所有读锁和写锁都被释放。

3、void unlock()

 释放读锁或写锁。如果当前线程持有读锁,则释放读锁。如果持有写锁,则释放写锁。尝试解除未锁定的锁是会导致程序终止。

4、bool tryLockForRead()

尝试获取读锁,如果获得了则返回true。如果另一个线程已经锁定写锁,则获取尝试将失败, 但它不会阻塞(与lockForRead()的不同)。

5、bool tryLockForRead(int timeout)

重载函数,如果另一个线程已经获取写锁,则会等待timeout毫秒看是否已经被释放了。 

6、bool tryLockForWrite()

尝试获取写锁,如果获得了则返回true,否则立即返回false。如果另一个线程获取了写或读锁,则尝试获取失败。

7、bool tryLockForWrite()

重载函数,如果另一个线程已经获取写或读锁,则等待timeout毫秒看释放已经释放了。 

五、示例 

// 共享数据变量
QString sharedData;
// 读写锁
QReadWriteLock lock;

// 读取操作线程
class ReaderThread : public QThread
{
public:
    void run() override
    {
        QReadLocker locker(&lock);
        qDebug() << "Read Data: " << sharedData;
    }
};

// 写入操作线程
class WriterThread : public QThread
{
public:
    void run() override
    {
        QWriteLocker locker(&lock);
        sharedData = "this is my city!";
        qDebug() << "Write Data: " << sharedData;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    ReaderThread thread1;
    WriterThread thread2;

    thread1.start();
    thread2.start();

    thread1.wait();
    thread2.wait();

    return a.exec();
}

运行结果:

相关文章:

  • linux常用命令大全(包括抓包、网络检测、路由等,做项目一点点总结而来!)
  • 请解释设备像素、CSS 像素、设备独立像素、DPR、PPI 之间的区别?
  • 【Agent的革命之路——LangGraph】工作流中的 map-reduce 模式
  • 【力扣】98.验证搜索二叉树
  • 线性表之顺序表
  • 《LeetCode 763. 划分字母区间 | 高效分割字符串》
  • linux-5.10.110内核源码分析 - bcm2711 pcie BAR地址分配
  • 牛客寒假训练营3
  • 芯片引脚描述或电路原理图中的Ipd、Ipu是什么意思?
  • fps武器系统6:随机弹道
  • vLLM专题(四)-故障排除
  • vue中如何动态的增减组件的类名(class)
  • OpenPose
  • 计算机世界的寻宝游戏:用C语言解密五大查找算法
  • 数据仓库与数据湖的协同工作:智慧数据管理的双引擎
  • 类和对象(5)——抽象类和接口
  • 云存储:云计算储存
  • 安卓设备调试h5页面(调试)
  • 量化交易入门指南
  • 《Stable Diffusion绘画完全指南:从入门到精通的Prompt设计艺术》-配套代码示例
  • 福建宁德市长张永宁拟任设区市党委正职,曾获评全国优秀县委书记
  • 从普通人经历中发现历史,王笛解读《线索与痕迹》
  • 时隔近4年再出征!长三丙成功发射通信技术试验卫星十九号
  • 加强战略矿产出口全链条管控工作部署会召开
  • 体坛联播|巴萨4比3打服皇马,利物浦2比2战平阿森纳
  • “80后”李灿已任重庆市南川区领导,此前获公示拟提名为副区长人选