Linux并发与竞争:从生活例子到内核实战
Linux并发与竞争:从生活例子到内核实战
一、并发与竞争:多车道公路的交通问题
想象一条四车道的高速公路(多核CPU),所有车辆(线程/进程)都想通过同一个收费站(共享资源)。如果没有交通规则(同步机制),就会发生:
- 数据竞争:两辆车同时抢一个收费口,导致碰撞(数据损坏)
- 死锁:四辆车互相阻挡,形成十字死锁(deadlock)
- 饥饿:大货车长期占用车道,小车永远过不去(starvation)
二、原子操作:不可分割的收费卡
2.1 原子操作原理
就像高速公路的ETC系统,收费过程(i++
这样的操作)必须一次性完成,不能被其他车辆打断。内核提供两类原子操作:
2.2 原子整形操作
atomic_t v = ATOMIC_INIT(0); // 初始化原子变量
atomic_inc(&v); // v++(不可打断)
int val = atomic_read(&v); // 安全读取
生活例子:银行金库的黄金数量统计,必须整块计算,不能出现"数到一半被其他人拿走"的情况。
2.3 原子位操作
unsigned long word = 0;
set_bit(0, &word); // 第0位置1(类似|=操作)
clear_bit(1, &word); // 第1位清0
适用场景:设备寄存器位操作、标志位管理。
三、自旋锁:不停旋转的收费站岗亭
3.1 自旋锁特性
- 忙等待:获取不到锁时,CPU会"空转"(就像司机在收费口不停探头张望)
- 短期持有:适合锁持有时间短于线程切换开销的情况
DEFINE_SPINLOCK(my_lock); // 定义锁spin_lock(&my_lock); // 获取锁
/* 临界区操作 */ // 只有一辆车能通过
spin_unlock(&my_lock); // 释放锁
3.2 锁的类型选择指南
锁类型 | 生活类比 | 适用场景 |
---|---|---|
普通自旋锁 | 普通收费岗亭 | 单核CPU/非中断上下文 |
IRQ自旋锁 | 应急车道专用岗亭 | 中断上下文共享数据 |
读写自旋锁 | ETC与人工通道分离 | 读多写少场景(如配置表) |
3.3 死锁预防(交通规则)
- 避免嵌套锁:不要在一个锁内获取另一个锁
- 统一顺序:多个锁按固定顺序获取
- 超时机制:
spin_trylock_irqsave
尝试获取锁
四、信号量:停车场剩余车位显示
4.1 信号量特点
- 允许睡眠:获取不到资源时,线程可以休眠(不像自旋锁那样空转)
- 资源计数:可以管理多个同类资源(如停车场剩余车位)
struct semaphore sem;
sema_init(&sem, 5); // 初始化5个车位down(&sem); // 获取车位(没有就睡觉)
/* 停车操作 */
up(&sem); // 释放车位
生活场景:
- 消费者生产者问题(停车场进出车辆)
- 打印机池管理(多个打印任务排队)
五、互斥体:单间厕所的门锁
5.1 互斥体特性
- 唯一访问:同一时刻只有一个线程能进入临界区
- 可睡眠:比自旋锁更适合长时间持有的场景
struct mutex my_mutex;
mutex_init(&my_mutex);mutex_lock(&my_mutex);
/* 临界区操作 */ // 如厕所单间使用
mutex_unlock(&my_mutex);
5.2 与自旋锁的对比
特性 | 自旋锁 | 互斥体 |
---|---|---|
等待方式 | CPU空转 | 线程休眠 |
开销 | 低(无上下文切换) | 高(需调度) |
持有时间 | 短(纳秒级) | 长(毫秒级) |
中断上下文 | 可用 | 不可用 |
六、实战选择流程图
graph TDA[需要保护共享资源?] -->|是| B{临界区执行时间}B -->|短(<10us)| C[自旋锁]B -->|长(>10us)| D{是否在中断上下文}D -->|是| CD -->|否| E[互斥体]A -->|否| F[无需同步]C --> G{是否需要读写分离}G -->|是| H[读写自旋锁]G -->|否| I[普通自旋锁]E --> J{资源是否可计数}J -->|是| K[信号量]J -->|否| E
七、常见错误案例
7.1 错误示范:中断中误用互斥体
// 错误代码(中断上下文不能睡眠)
irq_handler() {mutex_lock(&lock); // 可能引发系统崩溃/* 操作硬件寄存器 */mutex_unlock(&lock);
}// 正确做法(使用自旋锁)
irq_handler() {spin_lock_irqsave(&lock, flags);/* 操作硬件 */spin_unlock_irqrestore(&lock, flags);
}
7.2 错误示范:忘记释放锁
void func() {mutex_lock(&lock);if (error) {return; // 直接返回导致锁未释放!}mutex_unlock(&lock);
}// 正确做法(使用goto统一释放)
void func() {mutex_lock(&lock);if (error) {goto unlock;}
unlock:mutex_unlock(&lock);
}
八、性能优化技巧
-
减小临界区:只把必须保护的代码放在锁内
// 不好 mutex_lock(&lock); process_data(data); save_to_disk(data); mutex_unlock(&lock);// 优化后 mutex_lock(&lock); tmp = data; // 只保护数据拷贝 mutex_unlock(&lock); process_data(tmp); save_to_disk(tmp);
-
读写分离:读多写少时用读写锁
DEFINE_RWLOCK(rwlock);// 读线程 read_lock(&rwlock); /* 只读操作 */ read_unlock(&rwlock);// 写线程 write_lock(&rwlock); /* 写操作 */ write_unlock(&rwlock);
记住关键原则:锁的粒度要尽可能小,持有时间要尽可能短。
相关文章:
Linux并发与竞争:从生活例子到内核实战
Linux并发与竞争:从生活例子到内核实战 一、并发与竞争:多车道公路的交通问题 想象一条四车道的高速公路(多核CPU),所有车辆(线程/进程)都想通过同一个收费站(共享资源)…...
【金仓数据库征文】——金仓数据库:国产数据库的卓越之选
目录 一、金仓数据库的核心技术优势 (一)强大的事务处理能力 (二)高度安全 (三)全面兼容与深度适配 (四)强大的扩展性 (五)智能便捷的工具 二、电信行…...
人脸识别考勤系统实现教程:基于Face-Recognition、OpenCV与SQLite
引言 随着人工智能技术的飞速发展,人脸识别技术已广泛应用于安防、金融、教育等多个领域。本文将带领大家利用Python的face-recognition库、OpenCV和SQLite数据库,从零开始构建一个具备异常报警功能的人脸识别考勤系统。该系统能够实时检测视频流中的人…...
Golang 闭包学习
引言 在平常的 Go 语言开发中,常常需要将一段函数逻辑封装起来,异步执行、作为回调传递,甚至保持某些运行时状态。此时,闭包成为一种非常自然的编程手段。它允许我们在函数内部“记住”外部作用域中的变量,从而实现变…...
Trae+DeepSeek学习Python开发MVC框架程序笔记(四):使用sqlite验收用户名和密码
继续通过Trae向DeepSeek发问并修改程序,实现程序运行时生成数据库,用户在系统登录页面输入用户名和密码后,控制器通过模型查询用户数据库表来验证用户名和密码,验证通过后显示登录成功页面,验证失败则显示登录失败页面…...
【mdlib】0 全面介绍 mdlib - Rust 实现的 Markdown 工具集
mdlib 是由开发者 bahdotsh 创建的一个多功能 Markdown 工具集合,包含两个主要组件:一个轻量级 Markdown 解析库和一个功能完善的个人 Wiki 系统。该项目完全采用 Rust 实现,兼具高性能与跨平台特性。 核心组件 Markdown 解析库 特性&#…...
使用Django REST Framework快速开发API接口
以下是使用 Django 和 Django REST Framework (DRF) 开发 API 接口的核心步骤,涵盖模型、迁移、序列化、视图、路由等关键环节: 前言 什么是DRF? Django REST Framework(DRF) 是基于Django的一个强大且灵活的工具包&…...
Vue3项目中 npm 依赖安装 --save 与 --save-dev 的区别解析
这两个命令的区别如下: bash npm install --save types/crypto-js # 安装到 dependencies(生产依赖) npm install --save-dev types/crypto-js # 安装到 devDependencies(开发依赖) 核心区别 依赖分类不同…...
开源模型应用落地-语音合成-MegaTTS3-零样本克隆与多语言生成的突破
一、前言 在人工智能技术飞速发展的今天,文本转语音(TTS)技术正以前所未有的速度改变着人机交互的方式。近日,字节跳动与浙江大学联合推出了一款名为MegaTTS3 的开源TTS模型,再次刷新了行业对高质量语音合成的认知。作为一款轻量化设计的模型,MegaTTS3以仅0.45亿参数 的规…...
connection.cursor() 与 models.objects.filter
在 Django 中操作数据库时,connection.cursor() 和 models.objects.filter 是两种不同的方式,各有特点和适用场景: models.objects.filter (ORM 方式) 特点: 基于 Django 的 ORM(对象关系映射)框架&am…...
深入浅出JavaScript常见设计模式:从原理到实战(1)
深入浅出JavaScript常见设计模式:从原理到实战(1) 设计模式是一种在特定情境下解决软件设计中常见问题的通用方案或模板。在特定的开发场景中使用特定的设计模式,可以提升代码质量,增强代码可读性和可维护性,提高团队开发效率&…...
RCE学习
一、远程代码执行漏洞 1. 远程代码执行的定义 定义:远程代码执行漏洞(Remote Code Execute,简称RCE)是指程序预留了执行命令或代码的接口并被黑客利用的漏洞。广义上也包括远程命令执行(Remote Command Execute&…...
Redis安装及入门应用
应用资料:https://download.csdn.net/download/ly1h1/90685065 1.获取文件,并在该文件下执行cmd 2.输入redis-server-lucifer.exe redis.windows.conf,即可运行redis 3.安装redis客户端软件 4.安装后运行客户端软件,输入链接地址…...
【棒球运动】户外运动安全技巧·棒球1号位
以棒球运动为例,在棒球这项结合力量、速度与策略的户外运动中,安全防护是保障运动表现的核心。以下是针对棒球特点的户外安全指南,涵盖装备、环境与行为规范三大维度: 一、场景化防护装备选择 击球场景 击球手需佩戴双重防护头盔…...
卸载rpm包
昨天了解了查询rpm包的流程和命令,那么今天了解一下删除rpm包的语法,那么话不多说,来看. 1.基本语法 rpm -e RPM包的名称 注:e erase擦除 2.案例 删除firefox软件包 :rpm -e firefox 3.细节讨论 1.如果其它软件包依赖于要卸载的软件包,卸载时…...
【AI提示词】艺人顾问
提示说明 专业艺人顾问,专注于为客户提供全面的艺术、娱乐和商业咨询服务,帮助他们在竞争激烈的行业中树立品牌影响力,提升市场竞争力 提示词 # Role: 艺人顾问## Profile - language: 中文 - description: 专业艺人顾问,专注于…...
第七部分:向量数据库和索引策略
什么是矢量数据库? 简单来说,向量数据库是一种专门化的数据库,旨在优化存储和检索以高维向量形式表示的文本。 为什么这些数据库对RAG至关重要?因为向量表示能够在大规模文档库中进行高效的基于相似性的搜索,根据用户…...
26考研|数学分析:数项级数
数项级数这一章的开始,开启了新的关于“级数”这一新的概念体系的学习进程,此部分共包含四章的内容,分别为数项级数、函数项级数、幂级数以及傅里叶级数。这一章中,首先要掌握级数的相关概念与定义,重难点在于掌握判断…...
2025 年免费 Word 转 PDF 转换器有哪些?
我们列出了最好的 Word 到 PDF 转换器,以便轻松轻松地将 .doc 文件导出到 .pdf 而不会丢失原始格式。 尽管 Microsoft 365 包含一个 Word 版本,该版本可以将您正在处理的 .docx 文档无缝导出为 PDF 格式,但仍在使用旧版 Word 的人可能缺少此…...
【Spring Boot】深入解析:#{} 和 ${}
1.#{} 和 ${}的使用 1.1数据准备 1.1.1.MySQL数据准备 (1)创建数据库: CREATE DATABASE mybatis_study DEFAULT CHARACTER SET utf8mb4;(2)使用数据库 -- 使⽤数据数据 USE mybatis_study;(3ÿ…...
SpringMVC知识体系
SpringMVC 知识体系 1. SpringMVC 基础 MVC 设计模式 Model: 模型层,处理业务逻辑View: 视图层,负责界面展示Controller: 控制层,处理请求并协调模型和视图 核心组件 DispatcherServlet: 前端控制器HandlerMapping: 处理器映射Controller: …...
如何将 PDF 中的文本提取为 JSON 格式
一些 PDF 文件是“带标签”的,意味着它们包含关于文件结构的信息。这种结构作为元数据嵌入在 PDF 中,由一系列标签组成,用于标记诸如标题、段落、列表、表格和图像等元素。 这非常类似于 HTML,其中的文本包含在具有语义意义的元素…...
深度解析:基于Python的微信小程序自动化操作实现
引言 在当今数字化时代,自动化技术正在改变我们与软件交互的方式。本文将深入解析一个使用Python实现的微信小程序自动化操作脚本,该脚本能够自动识别屏幕上的特定图像并执行点击操作。这种技术在自动化测试、批量操作和效率工具开发中有着广泛的应用前…...
【网络安全】网络钓鱼的类型
1. 网络钓鱼简介 网络钓鱼是最常见的社会工程学类型之一,它是一种利用人为错误来获取私人信息、访问权限或贵重物品的操纵技术。之前,您学习了网络钓鱼是如何利用数字通信诱骗人们泄露敏感数据或部署恶意软件的。 有时,网络钓鱼攻击会伪装成…...
Python----深度学习(基于深度学习Pytroch线性回归和曲线回归)
一、引言 在当今数据驱动的时代,深度学习已成为解决复杂问题的有力工具。它广泛应用于图像识别、自然语言处理和预测分析等领域。回归分析是统计学的一种基础方法,用于描述变量之间的关系。通过回归模型,我们可以预测连续的数值输出…...
重构智能场景:艾博连携手智谱,共拓智能座舱AI应用新范式
2025年4月24日,智能座舱领域创新企业艾博连科技与国产大模型独角兽智谱,在上海国际车展艾博连会客厅签署合作协议。双方宣布将深度整合智谱在AI大模型领域的技术积淀与艾博连在汽车智能座舱场景的落地经验,共同推进下一代"有温度、懂需求…...
Streamlit从入门到精通:构建数据应用的利器
在数据科学与机器学习日益普及的今天,如何快速将模型部署为可交互的应用成为了许多数据科学家的重要任务。Streamlit,作为一个开源的Python库,专为数据科学家设计,能够帮助我们轻松构建美观且直观的Web应用。本文将从入门到精通&a…...
4.1.1 类的序列化与反序列化(XmlSerializer)
本文介绍XML序列化和反序列化操作 本例子中被序列化的类(Devices)中有一个List,其元素类型为:DigitalInputInfo. 序列化以及反序列化都很简单: 序列化:即把类的对象输出到文件中。 StreamWriter streamWriter new StreamWriter(filePath); …...
新增优惠券
文章目录 概要整体架构流程技术细节小结 概要 接口分析 一个基本的新增接口,按照Restful风格设计即可,关键是请求参数。之前表分析时已经详细介绍过这个页面及其中的字段,这里不再赘述。 需要特别注意的是,如果优惠券限定了使…...
Qt 处理 XML 数据
在 Qt 中,处理 XML 数据通常使用 Qt 提供的 QDomDocument、QXmlStreamReader 和 QXmlStreamWriter 类。这些类可以帮助你读取、修改和写入 XML 数据。 1. 使用 QDomDocument 处理 XML QDomDocument 提供了对 XML 文档的 DOM(Document Object Model&…...
STM32F407使用ESP8266实现阿里云OTA(下)
文章目录 前言一、函数分析1.get_bin()函数2.download_bin()函数3.串口1中断函数二、完整工程分析前言 从上一章中,我们已经成功连接阿里云并且成功拿到了升级包的下载地址,在本文我们将升级包下载下来并且存储到SD卡中,最终将程序写入FLASH中完成APP的跳转,至此我们的OTA…...
树型结构(知识点梳理及例题精讲)
大家好啊,这一集,我们来学习树型结构,请确保看完预习篇,再来看此篇哦 树型结构(预习课)-CSDN博客 话不多说,直接开讲 -------------------------------------------------------分割线-------…...
使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
使用HYPRE库并行装配IJ稀疏矩阵指南 HYPRE是一个流行的并行求解器库,特别适合大规模稀疏线性系统的求解。下面介绍如何并行装配IJ格式的稀疏矩阵,包括预先分配矩阵空间和循环使用。 1. 初始化矩阵 首先需要创建并初始化一个IJ矩阵: #incl…...
win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法
现象: 1. 当时新建运行的资源管理器的任务卡了或者原本资源管理器卡了 比如:当时在文本框中输入explorer 注:explorer.exe是Windows的文件资源管理器,它用于管理Windows的图形外壳,包括桌面和文件管理 按住CtrlAltEs…...
C语言编程--15.四数之和
题目: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复)&…...
从单机工具到协同平台:开源交互式模拟环境的技术演进之路
从单机工具到协同平台:开源交互式模拟环境的技术演进之路 一、引言:从“孤岛”到“生态”的模拟技术变革 二十年前,模拟软件如LAMMPS(分子动力学)、ANSYS(工程仿真)以单机版为主,用…...
Python函数与模块笔记
Python函数与模块笔记 目录 函数 无参函数带参函数变量作用域Lambda函数常用内置函数 模块与包 模块的定义与导入包的使用常用模块(keyword、random、sys、time) 一、函数 1. 无参函数 定义语法: def 函数名(): 代码块 return [表达式]…...
Jenkins:开启高效软件开发的魔法之门
一、Jenkins 是什么 Jenkins 是一款基于 Java 开发的开源持续集成工具,在软件开发流程中占据着举足轻重的地位。它的前身是 Hudson ,于 2004 年由 Sun 公司的 Kohsuke Kawaguchi 开发,2011 年因商标纠纷更名为 Jenkins。发展至今,…...
正则表达式学习指南
正则表达式学习指南 在编程的世界里,正则表达式(Regular Expressions,简称regex)是一门不可或缺的艺术,它赋予了开发者强大的文本处理能力,让看似复杂的字符串匹配和替换任务变得简单而高效。本文旨在为初…...
React-组件通信
1、父子组件通信 (1)父传子(props 传值) // 父组件 function App() {const name 张三return (<div className"App"><Son name{name} /></div>); }// 子组件 function Son(props) {return (<div…...
MuJoCo 机械臂 PPO 强化学习逆向运动学(IK)
视频讲解: MuJoCo 机械臂 PPO 强化学习逆向运动学(IK) 代码仓库:https://github.com/LitchiCheng/mujoco-learning 结合上期视频,我们安装了stable_baselines3和gym,今天用PPO尝试强化学习得到关节空间到达…...
代码随想录算法训练营第一天:数组part1
今日学习的文章链接和视频链接 ● 自己看到题目的第一想法 ● 看完代码随想录之后的想法 ● 自己实现过程中遇到哪些困难 ● 今日收获,记录一下自己的学习时长 状态 思路理解完成 30% 代码debug完成 60% 代码模板总结并抽象出来 100% 题目 704 二分查找 题目链接…...
C++学习:六个月从基础到就业——STL算法(二)排序与变序算法
C学习:六个月从基础到就业——STL算法(二)排序与变序算法 本文是我C学习之旅系列的第二十六篇技术文章,也是第二阶段"C进阶特性"的第四篇,主要介绍C STL算法库中的排序和变序算法。查看完整系列目录了解更多…...
JVM性能优化之年轻代参数设置
一、引言 在Java应用开发中,性能问题往往是最难预测却又最影响用户体验的关键因素。即便代码逻辑完美,若JVM(Java虚拟机)配置不当,也可能导致频繁GC停顿、内存泄漏,甚至引发系统崩溃。JVM性能优化并非简单…...
A*迷宫寻路
二、实验内容 以寻路问题为例实现A*算法的求解程序,设计两种不同的估价函数: 1.设置两种地图: 根据题意,用矩阵设置两个地图。 地图1:设置5行5列的迷宫,代码如下: 地图2:设置20行…...
秒出PPT推出更强版本,AI PPT工具进入新纪元!
在现代职场中,PPT是我们沟通和展示信息的重要工具。无论是做产品演示,还是准备工作汇报,一份精美的PPT能大大提升演示效果。然而,传统的PPT制作往往需要消耗大量时间,尤其是在排版、设计和内容调整上。如今,…...
electron-updater实现自动更新
electron-updater 是一个专为 Electron 应用设计的自动更新工具,能够帮助开发者轻松实现跨平台的自动更新功能。它支持 Windows、macOS 和 Linux 系统,通过简单的配置即可集成到 Electron 应用中,自动检查应用的最新版本并在后台完成更新。el…...
Ubuntu22学习记录
Ubuntu22学习记录 虚拟机挂载共享文件夹离线安装.net core3.1离线安装mysql离线安装supervisor离线安装nginx开机自启 虚拟机挂载共享文件夹 sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other 挂载路径:/mnt/hgfs/离线安装.net core3.1 离线安装mysql 离线安装…...
【MinerU】:一款将PDF转化为机器可读格式的工具——RAG加强(Docker版本)
目录 创建容器 安装miniconda 安装mineru CPU运行 GPU加速 多卡问题 创建容器 构建Dockerfile文件 开启ssh服务,设置密码为1234等操作 # 使用官方 Ubuntu 24.04 镜像 FROM ubuntu:24.04# 安装基础工具和SSH服务 RUN apt-get update && \apt-get ins…...
leetcode 69和367
69. Sqrt(x) 代码: class Solution { public:int mySqrt(int x) {int left 0;int right x;long long mid 0;int res 0;long long temp 0;while(left < right){mid left ((right - left)>>1);temp mid*mid;if(temp x){res mid;break;}else if(te…...