linux 内核同步互斥技术之顺序锁

顺序锁

顺序锁区分读者和写者,和读写自旋锁相比,它的优点是不会出现写者饿死的情况。读者不会阻塞写者,读者读数据的时候写者可以写数据。顺序锁有序列号,写者把序列号加 1,如果读者检测到序列号有变化,发现写者修改了数据,将会重试,读者的代价比较高。
顺序锁支持两种类型的读者。
(1)顺序读者( sequence readers):不会阻塞写者,但是如果读者检测到序列号有变化,发现写者修改了数据,读者将会重试。
(2)持锁读者( locking readers):如果写者或另一个持锁读者正在访问临界区,持锁读者将会等待。持锁读者也会阻塞写者。这种情况下顺序锁退化为自旋锁。如果使用顺序读者,那么互斥访问的资源不能是指针,因为写者可能使指针失效,读者访问失效的指针会出现致命的错误。
顺序锁比读写自旋锁更加高效,但读写自旋锁适用于所有场合,而顺序锁不能适用于所有场合,所以顺序锁不能完全替代读写自旋锁。
顺序锁有两个版本。
(1)完整版的顺序锁提供自旋锁和序列号。
(2)顺序锁只提供序列号,使用者有自己的自旋锁。

 完整版的顺序锁


完整版的顺序锁的定义如下:
include/linux/seqlock.h
typedef struct {
    struct seqcount seqcount;
    spinlock_t lock;
} seqlock_t;

typedef struct seqcount {
    unsigned sequence;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
    struct lockdep_map dep_map;
#endif
} seqcount_t;

成员 seqcount 是序列号,成员 lock 是自旋锁。
定义并且初始化静态顺序锁的方法如下:DEFINE_SEQLOCK(x)
运行时动态初始化顺序锁的方法如下:seqlock_init(x)

顺序读者读数据的方法如下:
seqlock_t seqlock;
unsigned int seq;
do {
    seq = read_seqbegin(&seqlock);
    //读数据
} while (read_seqretry(&seqlock, seq));
首先调用函数 read_seqbegin 读取序列号,然后读数据,最后调用函数 read_seqretry 判断序列号是否有变化。如果序列号有变化,说明写者修改了数据,那么读者需要重试。
持锁读者读数据的方法如下:
seqlock_t seqlock;
read_seqlock_excl(&seqlock);
//读数据    
read_sequnlock_excl(&seqlock);

函数 read_seqlock_excl 有一些变体。
(1) read_seqlock_excl_bh():申请自旋锁,并且禁止当前处理器的软中断。
(2) read_seqlock_excl_irq():申请自旋锁,并且禁止当前处理器的硬中断。
(3) read_seqlock_excl_irqsave():申请自旋锁,保存当前处理器的硬中断状态,并且禁止当前处理器的硬中断。

读者还可以根据情况灵活选择:如果没有写者在写数据,那么读者成为顺序读者;如果写者正在写数据,那么读者成为持锁读者。方法如下:
seqlock_t seqlock;
unsigned int seq = 0;
do {
    read_seqbegin_or_lock(&seqlock, &seq);
    //读数据
} while (need_seqretry(&seqlock, seq));
done_seqretry(&seqlock, seq);
函数 read_seqbegin_or_lock 有一个变体。
read_seqbegin_or_lock_irqsave:如果没有写者在写数据,那么读者成为顺序读者;如果写者正在写数据,那么读者成为持锁读者,申请自旋锁,保存当前处理器的硬中断状态,并且禁止当前处理器的硬中断。

写者写数据的方法如下:
write_seqlock(&seqlock);
//写数据
write_sequnlock(&seqlock);

函数 write_seqlock 有一些变体。
(1) write_seqlock_bh():申请写锁,并且禁止当前处理器的软中断。
(2) write_seqlock_irq():申请写锁,并且禁止当前处理器的硬中断。
(3) write_seqlock_irqsave():申请写锁,保存当前处理器的硬中断状态,并且禁止当前处理器的硬中断。

函数 write_seqlock 的代码如下:
include/linux/seqlock.h
static inline void write_seqlock(seqlock_t *sl)
{
    spin_lock(&sl->lock);
    write_seqcount_begin(&sl->seqcount);
}
static inline void write_seqcount_begin(seqcount_t *s)
{
    write_seqcount_begin_nested(s, 0);
}
static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
{
    raw_write_seqcount_begin(s);
    …
}
static inline void raw_write_seqcount_begin(seqcount_t *s)
{
    s->sequence++;
    smp_wmb();
}

    写者释放顺序锁的执行过程是:首先把序列号加 1,序列号变成偶数,然后释放自旋锁。
 

   只提供序列号的顺序锁


只提供序列号的顺序锁的定义如下:
include/linux/seqlock.h
typedef struct seqcount {
    unsigned sequence;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
    struct lockdep_map dep_map;
#endif
} seqcount_t;
定义并且初始化静态顺序锁的方法如下:seqcount_t x = SEQCNT_ZERO(x);
运行时动态初始化顺序锁的方法如下:seqcount_init(s)

读者读数据的方法如下:
seqcount_t sc;
unsigned int seq;
do {
    seq = read_seqcount_begin(&sc);
    //读数据
} while (read_seqcount_retry(&sc, seq));

写者写数据的方法如下:
spin_lock(&mylock);/* 假设使用者定义了自旋锁mylock */
write_seqcount_begin(&sc);
//写数据
write_seqcount_end(&sc);
spin unlock(&mylock);
 

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

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

相关文章

影视泛目录如何快速提升百度,搜狗权重?

要想快速提升影视泛目录网站的百度、搜狗权重,需要注意以下几点: 【苹果影视泛目录】部分功能 1、泛目录自由控制不影响本身程序使用 2、开关控制正常采集数据拉取本地词库与本地描述 3、正常页面干扰码开关 4、蜘蛛白名单 5、泛目录防重复功能 6.8版本…

解决:Component name “index“ should always be multi-word

原因 要求组件名称以驼峰格式命名,自定义组件名称应该由多单纯组成,防止和html标签冲突,所以index.vue 会报错 解决 1、按照规则驼峰格式,如:appIndex.vue 2、若有.eslintrc.js文件,并在规则中(rules)关…

数据挖掘-08-基于Python实现时间序列分析建模(ARIMA 模型)(包括数据和代码)

文章目录 0. 数据代码下载1. 背景描述2. 预测目的3. 数据总览4. 数据预处理4.1数据描述性统计与清洗a. 导入程序库b. 读取数据c. 查看统计信息和空值d. 查看是否有重复数据以及清理重复数据e. 空值清理f. 针对清洗后的数据进行统计分析 5. 探索性数据分析5.1 数据分析 6. 构建 …

在线文本对比工具

在线文本对比工具: Diff Checker: 网址:https://www.diffchecker.com/ Text Compare: 网址:https://text-compare.com/ Mergely: 网址:https://www.mergely.com/ Draftable Compare: 网址:https://draftable.com/co…

猫粮哪个牌子质量好性价比高?盘点十款主食冻干猫粮品牌排行榜!

在过去的100多年里,猫咪主食市场一直被膨化猫粮主导。然而,随着猫咪频频出现猝死、失明、发育不良以及营养不良等问题,猫主人们开始质疑膨化粮是否最适合猫咪。于是,从上世纪90年代开始,出现了生骨肉喂养。生骨肉确实是…

网络安全——基于Snort的入侵检测实验

一、实验目的要求: 二、实验设备与环境: 三、实验原理: 四、实验步骤: 五、实验现象、结果记录及整理: 六、分析讨论与思考题解答: 七、实验截图: 一、实验目的要求: 1、掌握…

一、win10+yolov8+anaconda环境部署

1、安装anaconda (1)打开aonconda下载地址:https://www.anaconda.com/download,点击download下载。 2、下载完成后,双击打开,点击Next,I Agree,选择just me; 3、勾选…

Spring上下文之注解模块ConfigurationMethod

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

飞天使-docker知识点8-docker的资源限制

文章目录 容器资源限制示例 容器资源限制 Docker提供了多种资源限制的方式,可以根据应用程序的需求和系统资源的可用性进行选择。以下是一些常见的Docker资源限制及其使用情况:CPU限制:通过设置CPU的配额(quota)和周期…

网络(九)CanSM及达芬奇配置

【小猫爪】AUTOSAR学习笔记05-Communication Stack之CanSM模块-CSDN博客 上链接讲的非常好。 CanSM提供的函数。 C CanSM使用的函数:

spring mail 邮件发送demo

首先配置号邮件服务器(我用的是126邮箱),获取密钥: 进入下图的【邮箱中心】->点击右侧的齿轮按钮 接着,开启 下图位置 的 POP3/SMTP(我当时点击开启时,需要手机扫码认证下) 最后…

putIfAbsent、computeIfAbsent、computeIfPresent

putIfAbsent 判断是否存在,不存在则设置 hashmap.putIfAbsent(K key, V value) 例子如下: public static void main(String[] args) {//hashmap.putIfAbsent(K key, V value)HashMap hashMap Maps.newHashMap();hashMap.put("aa","on…

ConnectionError怎么解决

文章目录 解决思路lz的具体解决过程 解决思路 这个错误表明在尝试加载评价指标时,代码试图从 huggingface 下载文件,但由于代理错误而无法连接。 为了解决这个问题,你可以尝试以下几个步骤: 1.设置代理: 如果你在使…

Zabbix监控系统部署与管理

zabbix介绍 zabbix是⼀个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的免费开源解决⽅案。zabbix能监视各种⽹络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbix构成 zabbix由…

Windows进程机制

进程 进程要做任何事情,必须让一个线程在它的上下文运行。该线程负责执行进程地址空间包含的代码。每个进程至少要有一个线程来执行进程地址空间包含的代码。当系统创建一个进程的时候,会自动为进程创建第一个线程,这称为主线程(…

命令调用先构建hashTable

GPT 代码改 #include <stdio.h> #include <stdlib.h> #include <string.h>#define TABLE_SIZE 256struct Node {char *key;void *value;struct Node *next; };struct HashTable {struct Node *table[TABLE_SIZE]; };void initHashTable(struct HashTable *ha…

简单计算器

题目描述 一个最简单的计算器&#xff0c;支持 ,-,*,/ 四种运算。仅需考虑输入输出为整数的情况&#xff0c;数据和运算结果不会超过 int 表示的范围。然而&#xff1a; 如果出现除数为 0 的情况&#xff0c;则输出&#xff1a;Divided by zero!。 如果出现无效的操作符&…

GPT-AI导航

1. https://ai-bot.cn/ https://ai-bot.cn/

工业固体废物智能化综合管控平台

工业固体废物智能化综合管控平台&#xff0c;涵盖产废企业、运输企业、固废处置企 业等不同群体应用&#xff0c;根据不同群体设计不同的业务应用子系统功能&#xff0c;以及各个不 同群体的环保物联网平台子系统功能模块&#xff0c;同时具有移动端的应用APP。 建立产废企业端…