【Linux】系统编程线程读写者模式(C++)

news2024/11/19 19:39:14

目录

一、读写锁

二、读写锁接口

【2.1】设置读写优先

【2.2】初始化

【2.3】销毁

【2.4】加读锁

【2.5】加写锁

【2.6】解锁

三、读写锁实例


一、读写锁

                在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢? 有,那就是读写锁。

 

        这里默认是读锁优先的,因为读者非常的多,但是这样也就会导致写锁的饥饿问题。

        读者写者模型和生产者消费者模型的区别? 读者写者模型和生产者消费者模型最大的区别就是生产者生产数据之后,消费者就会将数据消费掉,其他消费者则无法享受该数据。而读者写者模型中写者进行数据的写入时,所有的读者都可以享受该数据,直到写者再次写入。

读者写者模型中的三重关系?

  • 写者和写者的关系:互斥。

  • 读者和读者的关系:共享。

  • 读者和写者的关系:互斥和同步(当写者进行数据写入时,读者不可以进行数据的读取,当读者进行数据的读取时,写者不可以进行数据的写入,同时读者必须等待写者把数据写完才可以进行数据的写入)。

既然读读不互斥,为何还要加读锁?

  • 如果只是读,是不需要加锁的,加锁本身就有性能上的损耗。

  • 如果读可以不是最新数据,也不需要加锁。

  • 如果读必须是最新数据,必须加读写锁。

  • 读写锁相较于互斥锁的优点仅仅是允许读读的并发,除此之外并无其他。

二、读写锁接口

【2.1】设置读写优先

int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref);
/*
    pref 共有 3 种选择
    PTHREAD_RWLOCK_PREFER_READER_NP (默认设置) 读者优先,可能会导致写者饥饿情况
    PTHREAD_RWLOCK_PREFER_WRITER_NP 写者优先,目前有 BUG,导致表现行为和
    PTHREAD_RWLOCK_PREFER_READER_NP 一致
    PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 写者优先,但写者不能递归加锁
*/

【2.2】初始化

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr);
// 功能: 初始化读写锁
// 参数说明:
// rwlock: 是要进行初始化的读写锁
// attr:是rwlock的属性,此参数一般不关注,可设为NULL

【2.3】销毁

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
// 功能: 销毁初始化的锁
// 参数说明:
// rwlock: 是需要进行销毁的锁

【2.4】加读锁

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

【2.5】加写锁

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

【2.6】解锁

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

三、读写锁实例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
​
int data = 0; // 全局读写临界资源
pthread_rwlock_t rwlock; // 全局读写锁
​
/* - 读者线程 
*/
void *Reader(void *arg)
{
    while (true)
    {
        // 加读锁
        pthread_rwlock_rdlock(&rwlock);
​
        std::cout << "reader down:" << data << std::endl;
​
        // 解锁
        pthread_rwlock_unlock(&rwlock);
        sleep(2);
    }
}
​
/* - 写者线程
*/
void *Writer(void *arg)
{
    while (true)
    {
        // 加写锁
        pthread_rwlock_wrlock(&rwlock);
​
        std::cout << "writer down:" << ++data << std::endl;
​
        // 解锁
        pthread_rwlock_unlock(&rwlock);
        sleep(1);
    }
}
​
/* - 程序入口函数 
*/
int main()
{
    // 初始化读写这锁
    pthread_rwlock_init(&rwlock, NULL);
    // 创建读者线程
    pthread_t r[5];
    pthread_create(&r[0], nullptr, Reader, nullptr);
    pthread_create(&r[1], nullptr, Reader, nullptr);
    pthread_create(&r[2], nullptr, Reader, nullptr);
    pthread_create(&r[3], nullptr, Reader, nullptr);
    pthread_create(&r[4], nullptr, Reader, nullptr);
​
    // 创建读者线程
    pthread_t w;
    pthread_create(&w, nullptr, Writer, nullptr);
​
    // 线程等待
    for (int i = 0; i < 5; i++)
    {
        pthread_join(r[i], nullptr);
    }
    pthread_join(w, nullptr);
​
    // 释放读写这锁
    pthread_rwlock_destroy(&rwlock);
    return 0;
}
​
// 打印结果:
reader down:0
writer down:1
writer down:2
reader down:2
reader down:2
reader down:2
reader down:2
reader down:2
writer down:3
writer down:4
reader down:4
reader down:4
reader down:4
reader down:4
reader down:4
writer down:5
writer down:6
reader down:6
reader down:6
reader down:6
reader down:6
reader down:6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1035557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口自动化测试之Mock

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; 1.Mock实现原理和实现机制 在某些时候&#xff0c;后端在开发接口的时候&#xff0c;处理逻辑非常复杂&a…

基于Java+SpringBoot+Vue+Uniapp奶茶在线下单小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌…

Linux 用户 用户组管理

用户 Linux系统是一个多用户多任务的分时操作系统&#xff0c;任何要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统。每个用户账号都拥有一个唯一的用户名和各自的口令。用户在登录时键入正确的用户名和口令后&a…

ubuntu22.04编译DPDK19.08.2注意事项

下载&#xff1a;http://fast.dpdk.org/rel/dpdk-19.08.2.tar.xz 解压&#xff1a;tar -xvf dpdk-19.08.2.tar.xz &#xff08;1&#xff09;设置环境变量和编译 cd dpdk-stable-19.08.2 export RTE_SDKpwd export RTE_TARTGETx86_64-native-linuxapp-gcc make config Tx86…

Ae 效果:CC Simple Wire Removal

Keying/CC Simple Wire Removal Keying/CC Simple Wire Removal CC Simple Wire Removal &#xff08;CC 简单线条移除&#xff09;通过在两点之间创建一条指定宽度&#xff08;厚度&#xff09;的连线&#xff0c;然后将连线区域内的像素按指定方式进行填充&#xff0c;从而实…

R语言非线性方程数值分析生物降解、植物生长数据:多项式、渐近回归、米氏方程、逻辑曲线、Gompertz、Weibull曲线...

全文链接&#xff1a;https://tecdat.cn/?p33742 在选择最佳拟合实验数据的方程时&#xff0c;可能需要一些经验。当我们没有文献信息时该怎么办&#xff1f;我们建立模型的方法通常是经验主义的。也就是说&#xff0c;我们观察过程&#xff0c;绘制数据并注意到它们遵循一定的…

Qt使用opencv操作摄像头的例子

概述 这是一个Qt使用opencv lib操作摄像头的例子 详细 一、简介 这是一个Qt使用opencv lib操作摄像头的例子 二、代码实现过程 新建一个VideoCapture对象&#xff0c;然后通过这个对象读取Mat图像数据&#xff0c;再讲Mat数据转成QImage显示在QLabel上。 VideoCapture既支持…

PythonWeb服务器(HTTP协议)

一、HTTP协议与实现原理 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于在网络上传输超文本数据的协议。它是Web应用程序通信的基础&#xff0c;通过客户端和服务器之间的请求和响应来传输数据。在HTTP协议中连接客户与服务器的…

读写分离MySQL

利用Mycat控制后台数据库的读写分离和负载均衡 利用主从复制思想,实现读写分离,主库写,从库读 从库最好不要写,因为从库写入的数据不能同步到主库,只有主库写的数据才能同步到从库 balance属性值对应的含义(负载均衡) 一主一从读写分离的弊端 主节点Master宕机以后,业务系统…

DN-DETR(CVPR 2022)

DN-DETR&#xff08;CVPR 2022&#xff09; Accelerate DETR Training by Introducing Query DeNoising 匈牙利匹配不稳定导致了早期训练阶段的优化目标不一致 同一个图像&#xff0c;query在不同时期会对不同对象进行匹配 DN-DETR在真实的GT上添加噪声&#xff1a;xywh&am…

OpenGLES:多纹理贴图,文字水印

一.概述 上一篇博客讲解了OpenGLES怎么实现单纹理贴图 仅仅只绘制一张图片是不过瘾的 本篇博客讲解如何通过多纹理贴图实现图片和文本水印效果 在单纹理贴图基础上&#xff0c;多纹理贴图的区别主要有两点&#xff1a; 纹理的生成、绑定等由单个变成多个文本内容先转换为B…

深度学习实战基础案例——卷积神经网络(CNN)基于Xception的猫狗识别|第2例

文章目录 一、环境准备二、数据预处理三、构建模型四、实例化模型五、训练模型5.1 构建训练函数5.2 构建测试函数5.3 开始正式训练 六、可视化精度和损失七、个体预测 我的环境&#xff1a; pytorch&#xff1a;2.0python&#xff1a;3.8jupyternotebook 一、环境准备 impor…

jmeter——接口压测和性能监测实践

一、安装JMeter 1. 在客户端机器上安装JMeter压测工具&#xff0c;我这里安装的版本是apache-jmeter-5.2.1&#xff0c;由于JMeter是JAVA语言开发的&#xff0c;所以安装JMeter压测工具前先安装JDK&#xff0c;一般安装JDK1.8及以上即可。安装完成后&#xff0c;如果客户端机器…

【广州华锐互动】利用VR开展工业事故应急救援演练,确保救援行动的可靠性和有效性

在工业生产中&#xff0c;事故的突发性与不可预测性常常带来巨大的损失。传统的应急演练方式往往存在场地限制、成本高、效果难以衡量等问题。然而&#xff0c;随着虚拟现实&#xff08;VR&#xff09;技术的快速发展&#xff0c;VR工业事故应急救援演练应运而生&#xff0c;为…

基于PLE结合卡尔曼滤波的RSSI定位算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ............................................................... for Num_xb Num_xb2Num_…

Elasticsearch 部署学习

文章目录 Elasticsearch 部署学习1. 单节点部署 elasticsearch1.1 部署 jdk1.2 下载 elasticsearch1.3 上传文件并修改配置文件1.4 启动1.5 问题总结1.6 浏览器验证 2. 集群部署 elasticsearch3. 常用命令4. Elasticsearch kibana安装:one: 参考部署文档:two: 下载对应版本的安…

75、SpringBoot 整合 MyBatis------使用 Mapper 作为 Dao 组件

总结&#xff1a; 添加一个User类和Mapper接口&#xff0c; 在Mapper接口这个类上面添加Mapper注解&#xff0c;就可以和数据库进行映射了&#xff0c; 然后在mapper接口写方法和sql&#xff0c; 在测试类进行测试。 pom文件就添加个mybatis-spring-boot-starter 的组件&#x…

C 语言简单入门

C 语言发展历史|标准 1972年&#xff0c;丹尼斯里奇&#xff08;Dennis Ritch&#xff09;和肯汤普逊&#xff08;Ken Tompson&#xff09;在贝尔实验室开发 UNIX 操作系统时基于 B 语言设计出 C 语言。 1987年&#xff0c;布莱恩柯林汉&#xff08;Brian Kernighan&#xff…

Java核心知识点整理大全5-笔记

书接上回Java核心知识点整理大全4-笔记_希斯奎的博客-CSDN博客 目录 3.4.1. HashMap&#xff08;数组链表红黑树&#xff09; 3.4.1.1. JAVA7 实现 3.4.1.2. JAVA8 实现 3.4.2. ConcurrentHashMap 3.4.2.1. Segment 段 3.4.2.2. 线程安全&#xff08;Segment 继承 ReentrantLo…