news 2026/5/1 5:48:58

单核系统的加锁问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
单核系统的加锁问题

单核 CPU 同一时间只能执行一个指令流,但中断的本质是 “抢占式打断”—— 即使是单核,正在执行的主程序(线程 / 进程)也可能被中断服务程序(ISR)打断,而如果主程序和 ISR 同时访问同一个共享资源(比如全局变量、硬件寄存器),就会导致数据竞争不一致

在单核下,主程序执行int count = interrupt_count时,若指令还没执行完就被中断抢占,ISR 修改了interrupt_count,会导致主程序读取到 “不完整” 的值(比如 32 位变量只读了低 16 位,高 16 位被中断修改)。

单核系统中 “锁” 的核心逻辑

单核的 “锁” 不是 “互斥”,而是 “防抢占”;

多核系统的锁(如自旋锁、互斥锁)是为了解决多个 CPU 核心同时访问同一资源的问题(比如核心 1 和核心 2 同时写一个全局变量);

单核系统的 “锁” 是为了解决中断 / 线程抢占导致的指令流打断问题(比如主程序刚读了变量的一半,就被中断服务程序(ISR)打断并修改了变量)。

核心是保护 “临界区”—— 把访问共享资源的代码段变成 “不可被打断” 的原子操作,实现方式只有两种:

方式 1:关 / 开中断(最常用)

这是单核系统的 “专属锁”,原理是禁止 CPU 响应中断,让临界区代码完整执行:

char buf[100]; int buf_wr = 0; // 临界区保护函数(底层依赖CPU架构指令) void lock() { __asm__("cli"); // x86:关闭中断;ARM用CPSID I } void unlock() { __asm__("sti"); // x86:开启中断;ARM用CPSIE I } // 主程序:安全写缓冲区 void write_buf(char c) { lock(); // 进入临界区,禁止中断打断 if (buf_wr >= 100) { unlock(); return; } buf[buf_wr] = c; buf_wr++; unlock(); // 退出临界区,恢复中断 } // ISR:本身是中断上下文,无需加锁(但要极简) void isr_uart() { lock(); // 注意:ISR中加锁是防止嵌套中断,不是防多核 if (buf_wr > 0) { uart_send(buf[0]); for (int i=0; i<buf_wr-1; i++) buf[i] = buf[i+1]; buf_wr--; } unlock(); }

方式 2:原子指令(仅适用于简单操作)

如果共享资源的操作能通过一条 CPU 指令完成(即 “原子操作”),可以不用显式关中断:

// 原子操作示例:x86的inc指令(一条指令完成自增) volatile int counter = 0; // 主程序:原子自增,无需关中断 void main() { __asm__("inc %0" : "=r"(counter) : "0"(counter)); } // ISR:同样原子自增 void isr_timer() { __asm__("inc %0" : "=r"(counter) : "0"(counter)); }

但这种场景非常有限(仅适用于单步读写 / 修改),大部分复杂操作(如缓冲区、链表)仍需关中断。

特殊情况:无需加锁的场景

只有满足以下所有条件时,单核系统才不需要为中断加锁:

  • 共享资源的操作是原子指令(如 x86 的inc指令,ARM 的ldrex/strex),CPU 能一条指令完成读写;
  • 主程序访问资源时,不依赖资源的多个状态(比如只单次读取,不做 “读 - 改 - 写”);
  • 中断服务程序(ISR)中不访问该资源,或访问逻辑不会和主程序冲突。

Linux 内核中单核系统的锁机制

核心结论:Linux 内核在单核系统下仍会使用锁,但锁的底层实现会 “退化” 为轻量级的抢占控制,而非真正的多核互斥

Linux 单核系统中,引发资源竞争的场景主要是:

  • 进程 / 线程的抢占式调度(高优先级线程抢占低优先级线程);
  • 中断上下文(硬件中断 / 软中断抢占进程上下文)。

锁的核心目的就是保护这两类场景下的共享数据一致性。

Linux 内核提供了多种锁(spinlock、mutex、raw_spinlock 等),但单核下的实现会大幅简化:

自旋锁(spinlock)—— 单核下的 “伪自旋”

自旋锁是内核中最基础的锁,设计初衷是多核场景下 “忙等” 不睡眠,但单核下自旋锁不会自旋

  • 多核:获取不到锁时,CPU 循环等待(自旋),直到锁释放;
  • 单核:获取锁时,直接关闭内核抢占(preempt_disable ()),释放锁时开启抢占(preempt_enable ())。
// 单核下的spin_lock实现 #define spin_lock(lock) preempt_disable() // 关闭抢占,无需自旋 #define spin_unlock(lock) preempt_enable() // 开启抢占 // 多核下的spin_lock实现(对比) #define spin_lock(lock) \ while (atomic_cmpxchg(lock, 0, 1)) {} // 循环自旋,直到拿到锁

互斥锁(mutex)—— 单核下仍可能睡眠

mutex 是 “睡眠锁”,即使在单核下,获取不到锁时仍会:

  1. 释放 CPU(调度其他进程);
  2. 等待锁释放后被唤醒。

但单核下 mutex 的竞争场景只有 “进程抢占”,没有多核竞争,因此底层调度逻辑更简单。

关中断类操作(底层基础)

Linux 内核提供了专门的关中断接口,是单核锁的底层支撑:

接口作用单核场景适用场景
local_irq_disable()关闭当前 CPU 的中断(单核即全局)保护被中断和进程共享的资源
local_irq_enable()开启当前 CPU 的中断配合关中断使用
preempt_disable()关闭内核抢占(不影响硬件中断)保护仅被进程抢占的共享资源
preempt_enable()开启内核抢占配合关抢占使用

内核锁的使用原则

  • 中断上下文(ISR)中:必须用spin_lock_irqsave()(关中断 + 关抢占),因为 ISR 会抢占进程上下文;
  • 纯进程上下文:用spin_lock()(仅关抢占)或 mutex 即可;
  • 避免长时间持有锁:尤其是关中断的锁,会导致中断延迟,影响系统响应。

单核 vs 多核 Linux 锁的核心区别

维度单核系统多核系统
自旋锁关闭抢占,无自旋自旋等待,直到获取锁
竞争来源进程抢占、中断抢占多核 CPU 同时访问 + 进程 / 中断抢占
锁的核心防止 “自己被打断”防止 “其他核心抢资源 + 自己被打断”
性能开销极低(仅修改抢占标志)较高(自旋等待或缓存一致性开销)

总结

  1. 单核必须要 “锁”:核心目的是防止中断 / 线程抢占导致共享资源访问不完整,而非多核的 “互斥”;
  2. 锁的实现核心:单核用 “关中断→操作资源→开中断” 保护临界区,而非多核的自旋锁 / 互斥锁;
  3. 关键区别:多核锁是 “防别人抢”,单核锁是 “防自己被打断”,但最终目的都是保证共享资源的一致性。
  4. Linux 单核内核仍用锁:核心是通过 “关抢占 / 关中断” 保护临界区,防止进程 / 中断抢占导致数据不一致;
  5. 自旋锁是核心优化点:单核下自旋锁退化为 “关抢占”,无自旋开销,这是 Linux 内核的关键优化;
  6. 使用场景分上下文:中断上下文必须关中断 + 锁,纯进程上下文仅需关抢占即可。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 15:04:48

好写作AI:你的“24小时杠精陪练”,如何把学术论证变成肌肉记忆?

当你发现&#xff0c;自己写出的论点能预判教授的每一个反驳时——别慌&#xff0c;可能只是你的AI“陪练”太敬业了。凌晨的图书馆&#xff0c;一场“诡异”的对话正在哲学系小刘的屏幕上展开。他刚敲下一行论点&#xff0c;对话框就弹出三条反击&#xff1a;“此处隐含的休谟…

作者头像 李华
网站建设 2026/4/29 22:59:05

Ollama平台最新翻译模型translategemma-27b-it上手教程

Ollama平台最新翻译模型translategemma-27b-it上手教程 1. 快速了解translategemma-27b-it translategemma-27b-it是Google基于Gemma 3模型系列推出的轻量级开源翻译模型&#xff0c;专门处理多语言翻译任务。这个模型支持55种语言的互译&#xff0c;最大的特点是体积相对较小…

作者头像 李华
网站建设 2026/4/18 5:57:22

基于小波神经网络的时间序列预测

基于小波神经网络的时间序列预测 内涵详细的代码注释时间序列预测是一个广泛的研究领域&#xff0c;涉及金融、气象、股票等多方面的应用。小波神经网络&#xff08;Wavelet Neural Network, WNN&#xff09;结合了小波变换&#xff08;Wavelet Transform, WT&#xff09;和神经…

作者头像 李华
网站建设 2026/4/13 15:45:37

小白必看!GME多模态向量一键部署教程,轻松实现跨模态搜索

小白必看&#xff01;GME多模态向量一键部署教程&#xff0c;轻松实现跨模态搜索 你是否试过用一句话描述一张图&#xff0c;却找不到匹配的图片&#xff1f;或者上传一张产品截图&#xff0c;想立刻找到对应的说明书、评测视频甚至用户反馈&#xff1f;又或者&#xff0c;面对…

作者头像 李华
网站建设 2026/4/29 23:29:56

一键部署Pi0机器人控制模型,打造你的专属AI助手

一键部署Pi0机器人控制模型&#xff0c;打造你的专属AI助手 你有没有想过&#xff0c;让机器人真正听懂你的话&#xff0c;看懂眼前的场景&#xff0c;然后精准执行动作&#xff1f;不是科幻电影里的桥段&#xff0c;而是今天就能上手的真实技术——Pi0视觉-语言-动作流模型。…

作者头像 李华
网站建设 2026/5/1 0:55:23

agent-tools 技能分析报告

agent-tools 技能分析报告技能用途agent-tools 基于 inference.sh CLI&#xff0c;提供对 150 AI 应用的统一调用能力&#xff0c;覆盖图像/视频生成、LLM 调用、搜索与社媒自动化等场景。适合以下用途&#xff1a;图像生成&#xff1a;通过 FLUX、Gemini、Grok 等模型生成图片…

作者头像 李华