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

一文读懂|内核顺序锁

Linux 内核有非常多的锁机制,如:自旋锁、读写锁、信号量和 RCU 锁等。本文介绍一种和读写锁比较相似的锁机制:顺序锁(seqlock)。

顺序锁与读写锁一样,都是针对多读少写且快速处理的锁机制。而顺序锁和读写锁的区别就在于:读写锁的读锁会阻塞写锁,而顺序锁的读锁不会阻塞写锁。

读锁原理

为了让读锁不阻塞写锁,读锁并不会真正进行上锁操作。那么读锁是如何避免在读取临界区数据时,数据被其他进程修改了?

为了解决这个问题,顺序锁使用了一种类似于版本号的机制:序号。序号是一个只增不减的计数器,可以从顺序锁对象的定义看出,如下代码所示:

typedef struct {struct seqcount seqcount; // 序号spinlock_t lock;          // 自旋锁,写锁上锁时使用
} seqlock_t;

在读取临界区数据前,首先需要调用 read_seqbegin() 函数来获取读锁,read_seqbegin() 函数的核心逻辑是读取顺序锁的序号。代码如下所示:

static inline unsigned read_seqbegin(const seqlock_t *sl)
{unsigned ret;repeat:// 读取顺序锁的序号ret = sl->sequence;// 如果序号是单数,需要重新获取if (unlikely(ret & 1)) {...goto repeat;}...return ret;
}

从上面的代码可以看出,read_seqbegin() 函数只获取顺序锁的序号,并不会进行上锁操作,所以读锁并不会阻塞写锁。

注意:序号是单数时需要重新获取的原因,会在分析写锁实现原理时说明。

既然读锁并不会进行上锁操作,如果在读取临界区数据时,数据被修改了怎么办呢?答案就是:在退出临界区时,比较一下当前顺序锁的序号跟之前读取的序号是否一致。如果一致表示数据没有被修改,否则说明数据已经被修改。如果数据被修改了,那么需要重新读取临界区的数据。

比较序号是否一致可以使用 read_seqretry() 函数,所以读锁的正确用法如下代码所示:

do {// 获取顺序锁序号unsigned seq = read_seqbegin(&seqlock);// 读取临界区数据...
} while (read_seqretry(&seqlock, seq)); // 对比序号是否一致?

read_seqretry() 函数的实现非常简单,如下所示:

static inline unsigned 
read_seqretry(const seqlock_t *sl, unsigned start)
{...return sl->sequence != start;
}

从上面代码可以看出,read_seqretry() 函数只是简单比较当前序号与之前读取到的序号是否一致。

写锁原理

从上面的分析可知,读锁是通过对比前后序号是否一致来判断数据是否被修改的。那么序号在什么时候被修改呢?答案就是:获取写锁时。

获取写锁是通过 write_seqlock() 函数来实现的,其实现也比较简单,代码如下所示:

static inline void write_seqlock(seqlock_t *sl)
{spin_lock(&sl->lock);sl->sequence++;...
}

write_seqlock() 函数首先会获取自旋锁(所以写锁与写锁之间是互斥的),然后对序号进行加一操作。所以,在修改临界区数据前,写锁先会增加序号的值,这样就会导致读锁前后两次获取的序号不一致。我们可以用下图来说明这种情况:

seqlock原理

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

可以看出,当在读临界区前后获取的序号值不一致时,就表示数据已经被修改,这时就需要重新读取被修改后的数据。

写锁解锁也很简单,代码如下:

static inline void write_sequnlock(seqlock_t *sl)
{...s->sequence++;spin_unlock(&sl->lock);
}

解锁也需要对序号进行加一操作,然后释放自旋锁。

由于 write_seqlock() 函数与 write_sequnlock() 函数都会对序号进行加一操作,所以解锁后,序号的值必定为双数。

我们在分析读锁时看到,如果序号是单数时会重新获取序号,直到序号为双数为止。这是因为序号单数时,表示正在更新数据。此时读取临界区的值是没有意义的,所以需要等到更新完毕再读取。

原文作者:Linux内核那些事

相关文章:

一文读懂|内核顺序锁

Linux 内核有非常多的锁机制,如:自旋锁、读写锁、信号量和 RCU 锁等。本文介绍一种和读写锁比较相似的锁机制:顺序锁(seqlock)。 顺序锁与读写锁一样,都是针对多读少写且快速处理的锁机制。而顺序锁和读写…...

openproject在docker下的安装

官方指引:https://www.openproject.org/docs/installation-and-operations/installation/docker/ 网友指引:https://blog.csdn.net/joefive/article/details/119409550 建个自己的数据文件夹: sudo mkdir -p /var/lib/openproject/{mydata…...

React【React是什么?、创建项目 、React组件化、 JSX语法、条件渲染、列表渲染、事件处理】(一)

文章目录 React是什么? 为什么要学习React React开发前准备 创建React项目 React项目结构简介 React组件化 初识JSX 渲染JSX描述的页面 JSX语法 JSX的Class与Style属性 JSX生成的React元素 条件渲染(一) 条件渲染 &#xff0…...

Ubuntu系统下配置 Qt Creator 输入中文、配置软件源的服务器地址、修改Ubuntu系统时间

上篇介绍了Ubuntu系统下搭建QtCreator开发环境。我们可以发现安装好的QtCreator不能输入中文,也没有中文输入法供选择,这里需要进行设置。 文章目录 1. 配置软件源的服务器地址2. 先配置Ubuntu系统语言,设置为中文3. 安装Fcitx插件&#xff…...

Ab3d.PowerToys 11.0.8614 Crack

版本 11.0.8614 修补程序 使用 MouseCameraController 移动相机时防止旋转 FreeCamera。 版本 11.0.8585 重大更改:由于专利问题删除了 ViewCubeCameraController - 请联系支持人员以获取更多信息以及如果您想继续使用此控件。添加了 CameraNavigationCircles 控件…...

汽车3D HMI图形引擎选型指南【2023】

推荐:用 NSDT编辑器 快速搭建可编程3D场景 2002年,电影《少数派报告》让观众深入了解未来。 除了情节的核心道德困境之外,大多数人都对它的技术着迷。 我们看到了自动驾驶汽车、个性化广告和用户可以无缝交互的 3D 计算机界面。 令人惊讶的是…...

Stable Diffusion stable-diffusion-webui开发笔记

https://lexica.art/ lexica.art 该网站拥有数百万Stable Diffusion案例的文字描述和图片,可以为大家提供足够的创作灵感。可以提供promt灵感 https://civitai.com/ Civitai是一个聚集AI绘图爱好者的社区,在此网站上有许多定制化的模型,特…...

利用MQ实现mysql与elasticsearch数据同步

流程 1.声明exchange、queue、RoutingKey 2. 在hotel-admin中进行增删改&#xff08;SQL&#xff09;&#xff0c;完成消息发送 3. 在hotel-demo中完成消息监听&#xff0c;并更新elasticsearch数据 4. 测试同步 1.引入依赖 <!--amqp--> <dependency><groupId&…...

linux免密登录最简单--图文详解

最简单的免密登录 1.A电脑生成秘钥 ssh-keygen -t rsa 2.A电脑将秘钥传给B电脑 ssh-copy-id root192.168.1.129 #将秘钥直接传给B电脑 需要输入B电脑的密码&#xff0c;可以看到成功。 3.测试 同理&#xff1a;如果B->A也需要免密登录&#xff0c;统一的操作。 大功告…...

HTTP/1.1协议中的请求报文

2023年8月30日&#xff0c;周三上午 目录 概述请求报文示例详述 概述 HTTP/1.1协议的请求报文由以下几个部分组成&#xff1a; 请求行&#xff08;Request Line&#xff09;请求头部&#xff08;Request Headers&#xff09;空行&#xff08;Blank Line&#xff09;请求体&a…...

攻防世界-Hear-with-your-Eyes

原题 解题思路 是一个没有后缀的文件&#xff0c;题目提示要用眼睛看这段音频&#xff0c;notepad打开文件&#xff0c;没什么东西。 加后缀zip再解压看看。 使用Audacity打开音频文件...

ZED相机获取图像python

import pyzed.sl as sl import cv2 import numpy as np import osclass CameraZed2:def __init__(self,resolutionNone,fps30,depthMode None):self.zed sl.Camera()self.input_type sl.InputType()self.init_params sl.InitParameters(input_tself.input_type)# 设置分辨率…...

Oracle系列之--Profile

Oracle系列之--Profile_oracle profile_楼兰过客的博客-CSDN博客...

学习Bootstrap 5的第四天

目录 表格 基础表格 实例 条纹表格 实例 带边框表格 实例 有悬停效果的行 实例 黑色/深色表格 实例 黑色/深色条纹表格 实例 可悬停的黑色/深色表格 实例 无边框表格 实例 上下文类 可用的上下文类&#xff1a; 实例 表头颜色 实例 小型表格 实例 响应…...

喜报 | 再度中标南网项目!AR 开启电力远程运维新智慧

近日&#xff0c;中国南方电网官网发布《2023年南方电网数字平台科技 (广东)有限公司物资品控远程协助软件采购项目中标公告》&#xff0c;ALVA Systems 凭借 ALVA Rainbow 创新应用竞得此标。 随着相关技术的逐步成熟&#xff0c;基础问题远程化解决已经在工业领域广泛应用。 …...

3.使用IDE的优点

IDE是集成开发环境&#xff1a;Integrated Development Environment的缩写。 1、优点 使用IDE的好处在于&#xff0c;可以把编写代码、组织项目、编译、运行、调试等放到一个环境中运行&#xff0c;能极大地提高开发效率。 IDE提升开发效率主要靠以下几点&#xff1a; 编辑器…...

ShopXO商城系统文件上传0Day代审历程

Git仓库&#xff1a; https://github.com/gongfuxiang/shopxo简介&#xff1a; 两天攻防中&#xff0c;某政局内网横向发现多网段服务器&#xff0c;该服务器搭建了ShopXO商城系统(后来发现是开发临时搭建的&#xff0c;准备做二开用的)。结果花了30来秒审了个垃圾Day拿下该服…...

【java】【项目实战】[外卖十二]【完结】项目优化(前后端分离开发)

目录 一、问题说明 二、前后端分离开发 1、介绍 2、开发流程 3、前端技术栈 三、Yapi 1、介绍 2、部署 3、使用 3.1 添加项目​编辑 3.2 添加分类​编辑 3.3 添加接口 3.4 运行 3.5 导出接口 3.6 导入数据 四、Swagger 1、介绍 2、使用方式 2.1 pom 2.2 导入…...

解决uniapp下拉框 内容被覆盖的问题

1. 下拉框 内容被覆盖的问题 场景: 现在是下拉框被表格覆盖了 解决办法: 在表格上添加css 样式来解决这个问题 .add-table{display: static;overflow: visible; } display: static: 将元素会按照默认的布局方式进行显示&#xff0c;不会分为块状或行内元素。 overflow: vi…...

论文解读 | KPConv——点云上的可形变卷积网络

原创 | 文 BFT机器人 《KPConv: Flexible and Deformable Convolution for Point Clouds》是一篇发表于2019年的研究论文&#xff0c;作者为Hugues Thomas、Charles R. Qi、Jean-Emmanuel Deschaud、Beatriz Marcotegui和Franois Goulette。这篇论文关注于点云数据上的卷积操作…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...