序列计数器和顺序锁 【ChatGPT】

简介: 序列计数器和顺序锁 【ChatGPT】

序列计数器和顺序锁

介绍

序列计数器是一种具有无锁读取器(只读重试循环)和无写入者饥饿的读者-写者一致性机制。它们用于很少写入数据的情况(例如系统时间),其中读者希望获得一致的信息集,并且愿意在信息发生变化时重试。

当读取端临界区的序列计数在开始时是偶数,并且在临界区结束时再次读取相同的序列计数值时,数据集是一致的。数据集中的数据必须在读取端临界区内部被复制出来。如果在临界区开始和结束之间序列计数发生了变化,读者必须重试。

写者在其临界区的开始和结束时递增序列计数。在开始临界区后,序列计数是奇数,并指示读者正在进行更新。在写端临界区结束时,序列计数再次变为偶数,这样读者就可以取得进展。

序列计数器写端临界区绝不能被读端部分抢占或中断。否则,由于奇数序列计数值和被中断的写者,读者将会因为整个调度器滴答而旋转。如果该读者属于实时调度类,则它可能会永远旋转,内核将会活锁。

如果受保护的数据包含指针,则无法使用此机制,因为写者可能会使读者正在跟踪的指针失效。

序列计数器(seqcount_t)

这是原始计数机制,不保护多个写者。因此,写端临界区必须由外部锁进行串行化。

如果写串行化原语未隐式禁用抢占,则必须在进入写端部分之前显式禁用抢占。如果读取部分可以从硬中断或软中断上下文中调用,则必须在进入写部分之前分别禁用中断或底半部。

如果希望自动处理写者串行化和非可抢占性的序列计数要求,请改用顺序锁(seqlock_t)。

初始化:

/* 动态 */
seqcount_t foo_seqcount;
seqcount_init(&foo_seqcount);
/* 静态 */
static seqcount_t foo_seqcount = SEQCNT_ZERO(foo_seqcount);
/* C99 结构初始化 */
struct {
        .seq   = SEQCNT_ZERO(foo.seq),
} foo;

写路径:

/* 禁用抢占的串行化上下文 */
write_seqcount_begin(&foo_seqcount);
/* ... [[写端临界区]] ... */
write_seqcount_end(&foo_seqcount);

读路径:

do {
        seq = read_seqcount_begin(&foo_seqcount);
/* ... [[读端临界区]] ... */
} while (read_seqcount_retry(&foo_seqcount, seq));

带关联锁的序列计数器(seqcount_LOCKNAME_t)

如序列计数器(seqcount_t)中所述,序列计数写端临界区必须进行串行化和非可抢占。此序列计数器的变体在初始化时将用于写者串行化的锁关联到序列计数器上,从而使lockdep能够验证写端临界区是否得到适当的串行化。

如果禁用了lockdep,则此锁关联是一个NOOP,既不会增加存储空间,也不会增加运行时开销。如果启用了lockdep,则锁指针将存储在结构seqcount中,并且lockdep的“锁已持有”断言将被注入到写端临界区的开始,以验证其是否得到适当的保护。

对于不隐式禁用抢占的锁类型,在写端函数中将强制执行抢占保护。

以下带关联锁的序列计数器已定义:

  • seqcount_spinlock_t
  • seqcount_raw_spinlock_t
  • seqcount_rwlock_t
  • seqcount_mutex_t
  • seqcount_ww_mutex_t

序列计数器的读取和写入API可以采用普通的seqcount_t或上述任何seqcount_LOCKNAME_t变体。

初始化(用支持的锁替换“LOCKNAME”):

/* 动态 */
seqcount_LOCKNAME_t foo_seqcount;
seqcount_LOCKNAME_init(&foo_seqcount, &lock);
/* 静态 */
static seqcount_LOCKNAME_t foo_seqcount =
        SEQCNT_LOCKNAME_ZERO(foo_seqcount, &lock);
/* C99 结构初始化 */
struct {
        .seq   = SEQCNT_LOCKNAME_ZERO(foo.seq, &lock),
} foo;

写路径:与序列计数器(seqcount_t)中的相同,同时从已获取关联写串行化锁的上下文中运行。

读路径:与序列计数器(seqcount_t)中的相同。

锁定序列计数器(seqcount_latch_t)

锁定序列计数器是一种多版本并发控制机制,其中嵌入的seqcount_t计数器的偶/奇值用于在受保护数据的两个副本之间进行切换。这使得序列计数器读取路径可以安全地中断自己的写端临界区。

当读端无法保护写端部分免受读者中断时,请使用seqcount_latch_t。这通常是在读端可以从NMI处理程序中调用时的情况。

有关更多信息,请查看raw_write_seqcount_latch()。

顺序锁(seqlock_t)

这包含了前面讨论的序列计数器(seqcount_t)机制,以及用于写者串行化和非可抢占性的嵌入式自旋锁。

如果读端部分可以从硬中断或软中断上下文中调用,请使用禁用中断或底半部的写端函数变体。

初始化:

/* 动态 */
seqlock_t foo_seqlock;
seqlock_init(&foo_seqlock);
/* 静态 */
static DEFINE_SEQLOCK(foo_seqlock);
/* C99 结构初始化 */
struct {
        .seql   = __SEQLOCK_UNLOCKED(foo.seql)
} foo;

写路径:

write_seqlock(&foo_seqlock);
/* ... [[写端临界区]] ... */
write_sequnlock(&foo_seqlock);

读路径,分为三类:

  1. 普通序列读取器永远不会阻塞写者,但如果检测到序列号的变化,它们必须重试,因为写者正在进行中。写者不会等待序列读取器:
do {
            seq = read_seqbegin(&foo_seqlock);
            /* ... [[读端临界区]] ... */
    } while (read_seqretry(&foo_seqlock, seq));
  1. 锁定读取器会在写者或另一个锁定读取器进行中时等待。进行中的锁定读取器还会阻止写者进入其临界区。此读锁是独占的。与rwlock_t不同,只有一个锁定读取器可以获取它:
read_seqlock_excl(&foo_seqlock);
/* ... [[读端临界区]] ... */
    read_sequnlock_excl(&foo_seqlock);
  1. 根据传递的标记,条件无锁读取器(如1)或锁定读取器(如2)。这用于避免在写活动急剧增加时无锁读取器饥饿(太多重试循环)。首先尝试无锁读取(传递偶数标记)。如果该尝试失败(返回奇数序列计数,用作下一次迭代标记),则无锁读取将转换为完全锁定读取,不需要重试循环:
/* 标记;偶数初始化 */
int seq = 0;
do {
            read_seqbegin_or_lock(&foo_seqlock, &seq);
/* ... [[读端临界区]] ... */
    } while (need_seqretry(&foo_seqlock, seq));
    done_seqretry(&foo_seqlock, seq);

API 文档

https://www.kernel.org/doc/html/v6.6/locking/seqlock.html#api-documentation

相关文章
|
2月前
|
Linux
为内核对象添加引用计数器(krefs)【ChatGPT】
为内核对象添加引用计数器(krefs)【ChatGPT】
35 14
|
2月前
锁统计 【ChatGPT】
锁统计 【ChatGPT】
|
2月前
|
安全 编译器 测试技术
锁类型及其规则 【ChatGPT】
锁类型及其规则 【ChatGPT】
|
6月前
|
人工智能 IDE Linux
chatgpt的ai编程工具
该内容是关于两个chatgpt的ai编程工具的安装和使用说明。Copilot的下载步骤包括在IDE的设置中搜索并安装插件,然后重启IDE并登录GitHub账户。使用时,通过写注释触发建议,用快捷键选择建议。启用或禁用Copilot可通过底部状态图标。另一个工具是Alibaba Cloud AI Coding Assistant (Cosy),同样在IDE的插件市场下载安装后重启。其详细使用方法建议参考官网。
299 0
|
3月前
|
人工智能 自然语言处理 搜索推荐
chatgpt这么火,现在AI搜索引擎有哪些呢?
国外AI搜索引擎包括ChatGPT,擅长自然语言处理与内容生成;Google Bard,提供智能个性化搜索体验;Microsoft Bing集成GPT模型增强智能检索;Perplexity AI以简洁答案及文献引用著称;Neeva强调隐私保护与无广告服务。国内方面,天工AI支持多种功能如知识问答与代码编程;腾讯元宝基于混元模型助力内容创造与学习;360AI搜索以精准全面的信息搜索见长;秘塔AI专注提升写作质量和效率;开搜AI搜索提供个性化智能搜索服务。以上引擎均利用先进AI技术提升用户体验。更多详情参阅[AI搜索合集](zhangfeidezhu.com/?page_id=651)。
109 8
chatgpt这么火,现在AI搜索引擎有哪些呢?
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题
HuggingGPT是一个框架,它使用大型语言模型(如ChatGPT)作为控制器来管理和协调Hugging Face上的AI模型,以语言作为通用接口解决多模态和领域的复杂AI任务。
56 0
HuggingGPT解析:使用 ChatGPT及HuggingFace上的族系解决AI问题
|
3月前
|
机器学习/深度学习 人工智能 算法
为什么ChatGPT等AI大模型都是基于Python开发?
为什么ChatGPT等AI大模型都是基于Python开发?
|
3月前
|
人工智能 自然语言处理 Linux
免费ChatGPT4o灵办AI可体验浏览器插件
灵办AI就是您所需的最佳助手!我们为您带来了一款多功能AI工具,ChatGPT4o不仅能为您提供精准翻译,还能满足您的对话需求、智能续写、AI搜索、文档阅读、代码生成与修正等多种需求。灵办 AI,真正让工作和学习变得轻松高效!一款多功能智能助手,旨在提升工作和学习效率。它提供实时翻译、对话问答、搜索、写作和网页阅读等服务,支持多种浏览器和操作系统,帮助用户随时获取信息,打破语言障碍,优化内容创作和信息处理。
114 0
|
3月前
|
Web App开发 人工智能 安全
Gemini vs ChatGPT:谷歌最新的AI和ChatGPT相比,谁更强?
Gemini vs ChatGPT:谷歌最新的AI和ChatGPT相比,谁更强?
|
3月前
|
人工智能 安全 机器人
ChatGPT 1岁:创新、争议和AI产生突破的一年
ChatGPT 1岁:创新、争议和AI产生突破的一年