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

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();
}
http://www.dtcms.com/a/108102.html

相关文章:

  • 前端计算机网络常问问题大全
  • 如何在服务器端配置SSH以允许密码认证
  • html5炫酷图片悬停效果实现详解
  • 【零基础入门unity游戏开发——2D篇】使用SpriteAtlas(精灵图集)打包图集,减少DrawCall提高性能
  • 第四章、Isaacsim在GUI中构建机器人(1): 添加简单对象
  • SQL复杂查询与性能优化:医药行业ERP系统实战指南
  • Linux 基础入门操作 第九章 进程间通信之有名管道
  • el-select+el-tree、el-select+vl-tree实现下拉树形选择
  • Linux中进程与计划任务
  • SpringMvc获取请求数据
  • HTML5 Canvas绘画板项目实战:打造一个功能丰富的在线画板
  • 配置 UOS/deepin 系统远程桌面,实现多台电脑协同办公
  • PHP 8.x:现代Web开发的性能与效率革命
  • 解码 __getitem__ 和 __len__ - 自定义序列的钥匙
  • Prompt攻击是什么
  • Go和Golang语言简介
  • 快速排序与归并排序
  • 【硬件视界10】网络硬件入门:音频设备详解:声卡与音响系统
  • 【区块链 + 可信存证】国链区块链可信存证系统| FISCO BCOS 应用案例
  • 使用Qemu模拟32位ARM系统
  • OpenCV图像形态学:原理、操作与应用详解
  • 前端实现单点登录(SSO)的方案
  • Pycharm(十二)列表练习题
  • mac环境中Nginx安装使用 反向代理
  • 通俗解释 TCP 的三次握手、四次挥手
  • 《深度探索:数据库树形数据遍历与节点更新的游标之道》
  • 在PyTorch中使用GPU加速:从基础操作到模型部署
  • React-01React创建第一个项目(npm install -g create-react-app)
  • 【扣子agent入门】搭建计算热量工作流
  • 【QT】构建项目