锁定课程 【ChatGPT】

简介: 锁定课程 【ChatGPT】

锁定课程

课程1:自旋锁

用于锁定的最基本原语是自旋锁:

static DEFINE_SPINLOCK(xxx_lock);
unsigned long flags;
spin_lock_irqsave(&xxx_lock, flags);
... 临界区域 ...
spin_unlock_irqrestore(&xxx_lock, flags);

上述代码始终是安全的。它会在本地禁用中断,但自旋锁本身将保证全局锁,因此它将保证在由该锁保护的区域内只有一个控制线程。即使在单处理器系统(UP)下,这也能很好地工作,因此代码在单处理器系统和多处理器系统(SMP)下都能正确工作,因此代码在单处理器系统和多处理器系统(SMP)下都能正确工作。

注意! 自旋锁对内存的影响进一步在《Documentation/memory-barriers.txt》中有详细描述:

  • 获取操作(ACQUIRE operations)
  • 释放操作(RELEASE operations)

上述内容通常相当简单(通常大多数情况下只需要一个自旋锁 - 使用多个自旋锁可能会使事情变得更加复杂甚至更慢,通常只有在已知需要分割的序列时才值得这样做:如果不确定,尽量避免使用)。

这确实是自旋锁中唯一真正困难的部分:一旦开始使用自旋锁,它们往往会扩展到你以前可能没有注意到的领域,因为你必须确保自旋锁正确地保护了它们被使用的所有共享数据结构。自旋锁最容易添加到完全独立于其他代码的地方(例如,没有其他人会触及的内部驱动程序数据结构)。

注意! 自旋锁只有在你还使用锁本身来跨CPU进行锁定时才是安全的,这意味着一切触及共享变量的东西都必须同意他们想要使用的自旋锁。

课程2:读-写自旋锁

如果你的数据访问具有非常自然的模式,通常你倾向于大部分时间从共享变量中读取,那么自旋锁的读-写锁(rw_lock)版本有时是有用的。它们允许多个读者同时处于同一临界区域,但如果有人想要更改变量,则必须获得独占的写锁。

注意! 读-写锁比简单自旋锁需要更多的原子内存操作。除非读取临界区域很长,否则最好只使用自旋锁。

这些例程看起来与上面的例程相同:

rwlock_t xxx_lock = __RW_LOCK_UNLOCKED(xxx_lock);
unsigned long flags;
read_lock_irqsave(&xxx_lock, flags);
.. 仅读取信息的临界区域 ..
read_unlock_irqrestore(&xxx_lock, flags);
write_lock_irqsave(&xxx_lock, flags);
.. 读取和独占写入访问信息 ..
write_unlock_irqrestore(&xxx_lock, flags);

上述类型的锁对于像链表这样的复杂数据结构可能是有用的,特别是在搜索条目而不更改列表本身时。读锁允许许多并发读者。任何更改列表的操作都必须获得写锁。

注意! RCU 更适合于列表遍历,但需要对设计细节进行仔细注意(参见《Using RCU to Protect Read-Mostly Linked Lists》)。

此外,你不能将读锁升级为写锁,因此如果你在任何时候需要进行任何更改(即使你不是每次都这样做),你必须在一开始就获得写锁。

注意! 我们正在努力在大多数情况下删除读-写自旋锁,因此请不要在没有共识的情况下添加新的读-写自旋锁(而是参见《RCU Concepts》获取完整信息)。

课程3:自旋锁再探

上面的单个自旋锁原语绝不是唯一的。它们是最安全的,也是在所有情况下都能工作的,但部分是因为它们是安全的,它们也相当慢。它们比需要的慢,因为它们必须禁用中断(在x86上只是一个指令,但这是一个昂贵的指令 - 在其他架构上可能更糟)。

如果你有一个情况,你必须跨多个CPU保护一个数据结构,并且你想使用自旋锁,你可以潜在地使用更便宜的自旋锁版本。如果你知道自旋锁从不在中断处理程序中使用,你可以使用非中断版本:

spin_lock(&lock);
...
spin_unlock(&lock);

(当然,读-写版本也是如此)。自旋锁将保证相同类型的独占访问,并且速度会更快。如果你知道所讨论的数据只会从“进程上下文”中操作,即没有涉及中断,这是有用的。

你不能在有中断与自旋锁交互的情况下使用这些版本的原因是你可能会遇到死锁:

spin_lock(&lock);
...
<- 中断到来:
        spin_lock(&lock);

其中一个中断尝试锁定已经锁定的变量。如果其他中断发生在另一个CPU上,这是可以的,但如果中断发生在已经持有锁的相同CPU上,这是不可以的,因为锁显然永远不会被释放(因为中断正在等待锁,而持有锁的CPU被中断打断,并且直到中断被处理后才会继续)。

(这也是自旋锁的irq版本只需要禁用_本地_中断的原因 - 在其他CPU上的中断中使用自旋锁是可以的,因为在另一个CPU上的中断不会打断持有锁的CPU,因此持有锁的CPU可以继续并最终释放锁)。

林纳斯

参考信息:

对于动态初始化,请使用适当的spin_lock_init()或rwlock_init():

spinlock_t xxx_lock;
rwlock_t xxx_rw_lock;
static int __init xxx_init(void)
{
     spin_lock_init(&xxx_lock);
     rwlock_init(&xxx_rw_lock);
     ...
}
module_init(xxx_init);

对于静态初始化,请使用DEFINE_SPINLOCK() / DEFINE_RWLOCK()或__SPIN_LOCK_UNLOCKED() / __RW_LOCK_UNLOCKED():

static DEFINE_SPINLOCK(xxx_lock);
相关文章
|
自然语言处理 知识图谱
ChatGPT - 高效的提问结构
ChatGPT - 高效的提问结构
69 0
|
28天前
|
机器人 芯片
ChatGPT提问技巧——对话提示
ChatGPT提问技巧——对话提示
|
25天前
|
数据采集 人工智能 自然语言处理
表格增强生成TAG登场:解锁AI自然语言与数据库的完美结合
【10月更文挑战第4天】表格增强生成(TAG)范式解锁了AI自然语言处理与数据库的深度融合,旨在让用户通过自然语言便捷地查询和管理数据。TAG结合了语言模型的强大推理能力和数据库系统的高效计算能力,通过查询合成、执行及答案生成三步完成复杂查询。相较于传统Text2SQL和RAG方法,TAG在准确性上显著提升,但其应用仍面临技术门槛和数据质量等挑战。[论文地址:](https://arxiv.org/pdf/2408.14717)
41 4
|
29天前
|
人工智能 安全 搜索推荐
ChatGPT高效提问——角色提示
ChatGPT高效提问——角色提示
|
30天前
|
机器学习/深度学习 自然语言处理
要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 21 章:课程学习提示
要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 21 章:课程学习提示
|
29天前
|
机器学习/深度学习 搜索推荐 UED
ChatGPT高效提问——说明提示技巧
ChatGPT高效提问——说明提示技巧
|
29天前
|
搜索推荐
ChatGPT高效提问—prompt实践(教师助手)
ChatGPT高效提问—prompt实践(教师助手)
|
3月前
|
机器学习/深度学习 人工智能 搜索推荐
🔥解锁AI魔法!生成式大模型入门,你的“提示词”就是金钥匙🗝️
【8月更文挑战第1天】在科技浪潮中,生成式大模型作为AI领域的明星,正引领创作革命。这些模型如GPT和DALL-E,通过深度学习技术,在海量数据中学习理解与创造内容。要驾驭这些模型,关键在于设计精妙的提示词。提示词不仅是简单的指令,更是激发AI创造力的灵魂。例如,创作关于“未来教育”的文章时,“2050年个性化学习如何颠覆传统教学?”比“未来教育”能引导生成更深入、生动的内容。在图像生成方面,详细描绘场景加上情感色彩的提示词,如“星空下的古老城堡”,能使生成的图像更加引人入胜。通过不断优化提示词,我们可以开启AI无限创意的大门,见证科技与艺术的完美融合。
61 7
|
6月前
|
人工智能 搜索推荐 机器人
解锁智能对话的新境界:欢迎体验ChatGPT
在这个信息爆炸的时代,每个人都需要一个能够理解我们、帮助我们、甚至在某些时刻启发我们的智能伙伴。ChatGPT正是为此而生。它不仅仅是一个聊天机器人,它是一个基于最前沿人工智能技术打造的对话伙伴,能够提供深度信息搜索、日常交流、学习辅导、编程帮助,以及无数你可能想不到的功能。
更好地提问ChatGPT_常用prompt表
更好地提问ChatGPT_常用prompt表
319 0