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

Linux 锁 (4) - seqlock

文章目录1. 前言2. seqlock 实现3. 小结4. 参考资料1. 前言限于作者能力水平本文可能存在谬误因此而给读者带来的损失作者不做任何承诺。2. seqlock 实现seqlock通过一个初始为 0 计数器实现writer和reader共享数据的读写同步。writer一方更新共享数据的步骤如下计数器 1计数变为奇数更新共享数据计数器再 1计数变为偶数reader一方读取共享数据的步骤如下循环读取计数器的值直到读到一个偶数值并返回记为S1读取共享数据再次读取计数的值直到读到一个偶数值并返回计为S2比较 S1 和 S2如果S1 S2则表明步骤2.读取的共享数据是最新的则可用否则跳到步骤1.再次读取。来看具体的实现代码// include/linux/seqlock.htypedefstructseqcount{unsignedsequence;#ifdefCONFIG_DEBUG_LOCK_ALLOC...#endif}seqcount_t;seqlock 初始化staticinlinevoid__seqcount_init(seqcount_t*s,constchar*name,structlock_class_key*key){/* * Make sure we are not reinitializing a held lock: */lockdep_init_map(s-dep_map,name,key,0);s-sequence0;}#defineseqcount_init(s)__seqcount_init(s,NULL,NULL)#defineSEQCNT_ZERO(lockname){.sequence0,SEQCOUNT_DEP_MAP_INIT(lockname)}初始化将seqcount::sequence设为0。writer更新共享数据writer更新共享数据的逻辑如下structseqcountseqlock;seqcount_init(seqlock);write_seqcount_begin(seqlock);// 更新 writer/reader 贡献的数据write_seqcount_end(seqlock);seqcount_init()初始化了锁的计数器为0这在前面已经分析这里不再赘述。来看write_seqcount_begin()和write_seqcount_end()。先看共享数据更新之前的write_seqcount_begin()staticinlinevoidwrite_seqcount_begin(seqcount_t*s){write_seqcount_begin_nested(s,0);}staticinlinevoidwrite_seqcount_begin_nested(seqcount_t*s,intsubclass){raw_write_seqcount_begin(s);...}staticinlinevoidraw_write_seqcount_begin(seqcount_t*s){s-sequence;/* 标记写开始: 奇数 *//* * 确保让系统中的所有 CPU 观察到: * s-sequence 操作, 在 锁保护的共享数据 的 更新操作 之前 完成. */smp_wmb();}再看共享数据更新之后的write_seqcount_end()staticinlinevoidwrite_seqcount_end(seqcount_t*s){...raw_write_seqcount_end(s);}staticinlinevoidraw_write_seqcount_end(seqcount_t*s){/* * 确保让系统中的所有 CPU 观察到: * s-sequence 操作, 在 锁保护的共享数据 的 更新操作 之后 完成. */smp_wmb();s-sequence;/* 标记写结束: 偶数 */}reader读取更新的共享数据reader读取共享数据的逻辑如下假设使用的struct seqcount名为seqlockunsignedlongseq;do{seqread_seqcount_begin(seqlock);// 读取共享数据}while(read_seqcount_retry(seqlock,seq));// 本次读取数据结束先看read_seqcount_begin()staticinlineunsignedread_seqcount_begin(constseqcount_t*s){...returnraw_read_seqcount_begin(s);}staticinlineunsignedraw_read_seqcount_begin(constseqcount_t*s){unsignedret__read_seqcount_begin(s);/* * 确保系统中所有 CPU 观察到: * __read_seqcount_begin() 对锁计数器 s-sequence 的读取操作, * 在接下来 对共享数据的读操作 之前 完成. * 也即按 writer 先递增(第 1 次)了 锁计数器 s-sequence, 然后 * 更新共享数据同样的顺序去读取。 */smp_rmb();returnret;}staticinlineunsigned__read_seqcount_begin(constseqcount_t*s){unsignedret;repeat:retREAD_ONCE(s-sequence);if(unlikely(ret1)){/* 奇数: 正在写 */cpu_relax();gotorepeat;/* 重复读取计数器直至写结束 */}returnret;/* 返回偶数计数器 */}再看read_seqcount_retry()staticinlineintread_seqcount_retry(constseqcount_t*s,unsignedstart){/* * 确保系统中所有 CPU 观察到: * __read_seqcount_retry() 对锁计数器 s-sequence 的读取操作, 在 对共享数据的读操作 * 之后 完成。 * 也即按 writer 先更新了共享数据然后第 2 次递增了 锁计数器 s-sequence 同样的顺序 * 去读取。 */smp_rmb();return__read_seqcount_retry(s,start);}staticinlineint__read_seqcount_retry(constseqcount_t*s,unsignedstart){returnunlikely(s-sequence!start);}当然上面reader的读取逻辑在writer首次更新共享数据前reader也能正确工作因为初始的计数值为 0是一个偶数。3. 小结seqlock适合保护快速读写的小量数据比单单保护单个数据 atomic 操作更进一步。类似于rwlockseqlock也是针对读多写少的场景但它改善了rwlock的writer的优先级低甚至极端情况下被饿死的问题seqlock的writer优先级更高它可以随时打断reader通过更新计数器。seqlock不会导致进程睡眠但也不会像 spinlock 那样禁用抢占一直在一个 CPU 上自旋seqlock持锁期间可能出现临界区代码被调度出去的情形。如果seqlock保护的共享数据包含指针则不宜使用 seqlock因为 writer 可能会使 reader 正在访问的指针无效因为 reader 工作的同时它无法阻止 writer 对共享数据的更新。最后seqlock无法串行化多个writer必须借助外部锁来实现这一点。4. 参考资料Sequence counters and sequential locks

相关文章:

Linux 锁 (4) - seqlock

文章目录1. 前言2. seqlock 实现3. 小结4. 参考资料1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. seqlock 实现 seqlock 通过一个初始为 0 计数器,实现 writer 和 reader 共享数据…...

无外网环境怎么办?银河麒麟V10离线安装全流程(含镜像挂载/yum源配置)

银河麒麟V10企业级离线部署实战指南:镜像挂载与本地yum源深度配置 在金融、政务等对数据隔离要求严格的行业场景中,服务器通常运行于物理隔离的内网环境。作为国产操作系统的代表,银河麒麟V10的离线部署能力直接关系到关键基础设施的运维效率…...

Power BI与Python集成:大数据分析更强大

Power BI与Python集成:大数据分析更强大 关键词:Power BI、Python、数据集成、可视化分析、大数据处理 摘要:本文将带您探索Power BI与Python集成的魔法——前者是微软推出的“数据可视化神器”,后者是“数据分析全能手”。通过两…...

别再只盯着ABAA了!SAP资产‘非计划折旧’(ABAA)的3个高级应用场景与配置要点

SAP资产非计划折旧(ABAA)的深度应用与实战指南 在SAP资产管理领域,ABAA事务代码作为"非计划折旧"的核心工具,其价值远超出基础操作手册中的简单定义。许多企业仅将其视为应急调整的权宜之计,却忽略了它在复杂业务场景下的战略价值。…...

实战分享:用Verilog在FPGA上实现SPI Flash控制器(支持M25P16芯片)

实战分享:用Verilog在FPGA上实现SPI Flash控制器(支持M25P16芯片) 在嵌入式存储系统开发中,SPI Flash因其接口简单、成本低廉而广受欢迎。本文将手把手带你实现一个完整的SPI Flash控制器,重点针对M25P16芯片的特性进行…...

第四篇:《东坡八首·其四》|低谷不怨天尤人,踏实深耕终有回甘

开篇:职场努力迟迟没结果?别慌,你只是在扎根蓄力很多职场人都陷入过这样的困境:明明脚踏实地做事,默默付出全力深耕,却迟迟看不到成果,升职加薪没踪影,项目推进遇阻碍,甚…...

LangGraph记忆系统深度对比:InMemoryStore和MemorySaver该如何选择?

LangGraph记忆系统深度对比:InMemoryStore和MemorySaver该如何选择? 在构建现代对话系统时,记忆管理是决定用户体验的关键因素之一。想象一下,当你与一个客服系统交流时,每次都需要重复自己的基本信息,这种…...

单细胞转录组分析流程:从细胞矩阵生成到聚类、注释与轨迹推断

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 摘要:单细胞RNA测序(scRNA-seq&…...

人工智能应用- 预测新冠病毒传染性:08. 定位显著变异点

更令人关注的是,M-H 模型还能定位病毒基因中对传播能力最敏感的突变位点。这是因为在模型设计时,科学家们为每个变异点都设置了一个“显著值”参数。模型训练结束后,那些显著值较大的变异点就被识别为对传染性影响较大的基因位置。图中的红色…...

人工智能应用- 预测新冠病毒传染性:07. 预测不同类型病毒的传播能力

研究者利用 M-H 模型对各个病毒变种的传播能力进行了研究,结果如图所示:图: AI 模型预测的病毒传播力。横轴为变种出现时间,纵轴为预测传播能力,表示为相对基本再生数(R/RA,其中 RA 是武汉变种的基本再生数…...

探索IEEE 39节点暂态模型:Simulink与PSCAD仿真之旅

IEEE39节点暂态模型,包括simulink与PSCAD两类仿真模型。 (运行时先运行m文件)IEEE39节点标准系统,标准算例数据,电源采用发电机模型,更能考虑完备暂态响应。 适合新手学习所用,减少搭建模型时间…...

永磁同步电机参数辨识仿真,基于递推最小二乘法RLS的永磁同步电机参数辨识,仿真程序加解析文档,包含

永磁同步电机参数辨识仿真,基于递推最小二乘法RLS的永磁同步电机参数辨识,仿真程序加解析文档,包含: 一份仿真程序 一份自己总结的算法解析文档 一份参考文献。 目前,常见的电机电气参数辨识算法有频率响应法、模型参考…...

Spine动画实战:手把手教你用‘摄影表’和关键帧,5分钟做个会动的表情包

Spine动画实战:5分钟用关键帧制作魔性表情包 记得第一次在群里看到朋友发的那个"疯狂点头"的柴犬表情包时,我被它魔性的节奏感彻底征服了。作为一个UI设计师,我立刻想知道这种流畅的循环小动画是怎么做出来的。试过AE后发现太重量级…...

最近在折腾TSP路径优化的时候,发现禁忌搜索和蚁群算法这对组合挺有意思。咱们直接上代码,边跑边聊这两种算法怎么把城市坐标玩出花来。(别慌,文末有完整代码打包)

基于matlab的禁忌搜索算法和蚁群优化算法优化TSP路径,动态输出路径规划过程及输出最小距离。 数据可更换自己的,程序已调通,可直接运行。先看禁忌搜索的暴力美学。这货核心就三招:禁忌表锁死局部最优、特赦规则放行优质解、邻域搜…...

毕业设计救星:手把手教你用KF-GINS搞定GNSS/INS松组合导航(附代码详解)

毕业设计实战:从零实现GNSS/INS松组合导航系统 第一次接触组合导航系统时,我被各种坐标系转换和状态方程搞得晕头转向。直到在GitHub上发现了KF-GINS这个开源项目,才真正理解了如何将理论转化为代码。本文将带你从环境搭建到完整实现&#xf…...

竞争性谈判实战指南:从文件准备到最终报价的5个关键决胜点

竞争性谈判实战指南:从文件准备到最终报价的5个关键决胜点 在服务类采购领域,竞争性谈判正成为越来越多采购方的首选方式。与传统的公开招标不同,这种采购方式更注重供需双方的深度互动,为供应商提供了更多展示综合实力的机会。对…...

GDPR与CCPA实战指南:企业数据隐私合规架构设计

1. 数据隐私合规的底层逻辑 第一次接触GDPR和CCPA时,我完全被那些晦涩的法律条文绕晕了。直到某次在超市结账,收银员问我是否要办理会员卡,突然意识到这就是最朴素的"数据交易"场景——用个人信息换取折扣。企业构建合规架构的本质…...

深入解析ASCAD数据集:从元数据到侧信道攻击实践

1. ASCAD数据集基础解析 第一次接触ASCAD数据集时,我和大多数研究者一样感到困惑——这个被广泛引用的侧信道分析基准数据集,实际操作起来却像在迷宫里找出口。经过半年的实战摸索,我终于理清了它的脉络。ASCAD全称"ANSSI Side-Channel …...

【开题答辩全过程】以 基于.NET MVC的婚庆服务系统设计为例,包含答辩的问题和答案

个人简介 一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等 开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。 感谢大家…...

【开题答辩全过程】以 基于 Python 的甘肃旅游微信咨询系统的设计与实现为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…...

Linux网络加速神器BBR实战:用CentOS7搭建高速下载节点的完整教程

CentOS 7 BBR加速深度优化:打造企业级高速传输节点 在数字化协作日益频繁的今天,跨国文件传输速度常常成为工作效率的瓶颈。我曾管理过一个跨国开发团队,每次同步Docker镜像时,2GB的文件需要耗费近40分钟,直到发现了BB…...

基于Docker与DDNSTO的Nas内网穿透Web服务实战指南

1. 为什么需要内网穿透? 很多朋友买了Nas后,发现只能在局域网内访问存储的文件和部署的服务,这就像买了一栋别墅却只能在后院活动一样浪费。想象一下这样的场景:你在公司想查看家里Nas上的文档,出差时想用手机访问家里…...

COMSOL仿真技术在静脉血管曲张与血管流分析中的应用

COMSOL静脉血管曲张仿真,COMSOL血管流仿真,静脉曲张这种病看着不严重,但发作起来真要命——小腿像爬满了蚯蚓,站着疼躺着酸。以前医生只能靠经验判断治疗方案,现在有了COMSOL这种神器,咱们可以先把血管模型…...

银河麒麟系统下telnet服务配置全攻略(附安全加固建议)

银河麒麟系统下telnet服务配置与安全加固实战指南 在企业级国产化替代浪潮中,银河麒麟操作系统凭借其高安全性和稳定性成为众多关键基础设施的首选。作为传统远程管理工具,telnet服务在内部运维场景中仍有一席之地,但其明文传输特性也带来显著…...

永磁同步电机新型滑模扰动观测器控制(NSMDO)+无差拍电流预测控制(DBCC) [1]速度环...

永磁同步电机新型滑模扰动观测器控制(NSMDO)+无差拍电流预测控制(DBCC) [1]速度环采用NSMDO [2]电流环采用DBCC 本系列仿真所使用的电机参数一致。永磁同步电机控制总绕不开抗干扰和动态响应这两个老问题,最…...

面试11-Agent如何自动接任务

一、整体场景与核心目标解释 首先,我们先明确这段代码要解决的核心问题: 在第9-10季的代码中,"队友代理(teammate agent)"只能在负责人(lead)明确分配任务时才工作,10个未…...

最长公共子序列(LCS)——从零开始的动态规划

LCS最长公共子序列:从理解到实现,一次讲透在字符串和动态规划的学习中,LCS(Longest Common Subsequence,最长公共子序列)是一个绕不开的经典问题。很多人一开始觉得它和“最长公共子串”差不多,…...

Matlab基于连续小波变换(CWT)批量生成时频图

Matlab基于连续小波变换(CWT),将一维信号批量生成时频图的源 此示例中,原始信号data是30*1280的格式,一共30条信号,信号长度为1280。 最终生成30张时频图。 生成的图像可用于后续的深度学习分类或其他处理。…...

手机摄像头背后的高速通道:深入浅出图解MIPI CSI-2数据流

手机摄像头背后的高速通道:深入浅出图解MIPI CSI-2数据流 当你用手机拍下一张照片时,图像数据从传感器到处理器的旅程堪比一场精密编排的接力赛。这场赛道的核心就是MIPI CSI-2协议——它如同一条隐形的高速公路,以每秒数GB的速度传输着海量图…...

PFC2D 中隧道开挖应力释放模拟:精准掌控比例的艺术

pfc2d隧道开挖考虑应力释放,可以指定应力释放的比例。在岩土工程数值模拟领域,PFC2D(Particle Flow Code in 2 Dimensions)是一款极为强大的工具,尤其是在隧道开挖模拟方面表现卓越。其中,考虑应力释放并能…...