Linux驱动学习笔记(三)
并发与竞争
1.在编写驱动程序的时候,要尽量避免让驱动程序存在并发和竞争,Linux内核里面提供了几种处理并发与竞争的方法,分别是:原子操作、自旋锁、信号量和互斥体。
- 原子操作:Linux的原子操作基于atomic_t数据类型(64位为atomic64_t),如下图:
对于64位常见的原子操作函数如下图所示:
原子位操作函数如下图所示:

- 自旋锁:当一个线程尝试获取锁时,如果该锁已经被其他线程持有,线程不会进入阻塞或睡眠状态,而是会持续不断地检查锁的状态,直到锁变为可用为止,这种检查过程称为“自旋”。Linux中的自选锁在内核源码目录下的头文件include/linux/spinlock_types.h中定义,如下图所示:
Linux中与自旋锁有关的函数如下图所示:
在访问临界资源的时候先申请自旋锁,获取到自旋锁以后就进入临界区,获取不到自旋锁就“原地等待”,退出临界区的时候要释放自旋锁。由于自旋锁会“原地等待”,而“原地等待”会继续占用CPU并消耗CPU资源,所以锁的时间不能太长,也就是临界区的代码不能太多。另外在自旋锁保护的临界区里面不能调用可能会导致线程休眠的函数,否则可能会发生死锁。自旋锁一般是用在多核的SOC上。如果中断服务函数里面要使用自旋锁,需要在驱动程序中使用spin_lock_irqsave(在获取锁之前,该函数会关闭本地中断并保存当前的中断状态,这是为了防止当前进程被中断打断,例如防止嵌套的中断操作或上下文切换)和spin_unlock_irqrestore(在释放锁时,该函数会将中断状态恢复到之前的状态)函数来申请自旋锁。在同一个函数里面多次获取自旋锁也会导致死锁。其他与自旋锁相关的API函数如下图:

- 信号量:信号量的本质是一个全局变量。信号量的值可以根据实际情况来自行设置(取值范围大于等于0)当有线程来访问资源时,信号量执行“减一”操作,访问完以后再执行“加一”操作。Linux中的信号量在文件include/linux/semaphore.h中定义,如下图所示:
Linux中与信号量相关的函数如下图:
down() 是一种传统的信号量获取函数,它会尝试获取信号量,如果信号量的计数值大于 0,down() 会直接减少信号量计数并返回0表示成功。如果信号量计数为 0,调用该函数的进程会被阻塞,直到信号量变得可用。与spin_lock()的盲等不一样,这里的阻塞指的是进程会进入睡眠状态,并且会被放入一个信号量的等待队列中。此时该进程不会继续占用 CPU,其他进程可以继续执行,直到信号量变为可用状态,内核会唤醒该进程,让它重新竞争信号量。down_interruptible() 与 down() 的行为类似,主要区别在于它能响应信号(即可以被中断)。如果信号量不可用,调用该函数的进程会被阻塞,直到信号量变为可用,或者进程接收到中断信号(如用户请求的 SIGINT)从而被打断。在这种情况下,down_interruptible() 会返回一个负值,表示进程因中断而被唤醒。与信号量有关约束如下:信号量的值不能小于0;访问共享资源时,信号量执行“减一”操作,访问完成后在执行“加一”操作;当信号量的值为0时,想访问共享资源的线程必须等待,直到信号量大于0时,等待的线程才可以访问;因为信号量会引起休眠,所以中断里面不能用信号量;共享资源持有时间比较长,一般用信号量而不用自旋锁;在同时使用信号量和自旋锁的时候,要先获取信号量,再使用自旋锁,因为信号量会导致睡眠。
- 互斥锁:同一个资源同一个时间只有一个访问者在进行访问,其他的访问者访问结束以后才可以访问这个资源,这就是互斥。互斥锁和信号量值为1的情况很类似,但是互斥锁更简洁,更高效。Linux中用mutex结构体来描述互斥锁,定义在文件include/linux/mutex.h中,如下图所示:
Linux中与互斥锁相关的函数有:
mutex_lock()函数在无法获取互斥锁时会阻塞进入休眠状态,这里的休眠类似于信号量,休眠直到被释放互斥锁的进程唤醒。由于互斥锁会导致休眠,所以在中断里面不能用互斥锁。同一时刻只能有一个线程持有互斥锁,并且只有持有者可以解锁。不允许递归上锁和解锁。
2.ubuntu中的Linux源码路径为:/lib/modules/5.15.0-127-generic/build/。
相关文章:
Linux驱动学习笔记(三)
并发与竞争 1.在编写驱动程序的时候,要尽量避免让驱动程序存在并发和竞争,Linux内核里面提供了几种处理并发与竞争的方法,分别是:原子操作、自旋锁、信号量和互斥体。 原子操作:Linux的原子操作基于atomic_t数据类型…...
【QT5 多线程示例】互斥锁
互斥锁 互斥锁介绍:【C并发编程】(三)互斥锁:std::mutex。原理都一样,这里就不赘述了。 QMutex 是 Qt 框架中提供的一个互斥锁类,主要包括以下成员函数: lock():试图锁定互斥量。…...
SaaS系统的销售微服务与权限微服务边界设计
在设计SaaS系统的销售微服务与权限微服务的边界时,需要结合领域驱动设计(DDD)和微服务拆分原则,确保高内聚、低耦合。以下是结合微服务架构原则、多租户SaaS需求及权限管理场景的完整设计方案,整合了权限服务与销售服务…...
leetcode热题100道——两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…...
C语言经典代码练习题
1.输入一个4位数:输出这个输的个位 十位 百位 千位 #include <stdio.h> int main(int argc, char const *argv[]) {int a;printf("输入一个4位数:");scanf("%d",&a);printf("个位:%d\n"…...
Git远程拉取和推送配置
Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景:换新电脑后使用Git进行代码拉取和推送过程中,提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次…...
MySQL WHERE 子句详解
MySQL WHERE 子句详解 引言 在数据库操作中,WHERE 子句是用于筛选记录的重要工具。它允许我们在查询中指定条件,从而只选择满足特定条件的记录。本文将详细介绍 MySQL 中的 WHERE 子句,包括其语法、用法以及一些高级技巧。 WHERE 子句的基…...
基于SpringBoot+Vue3实现的宠物领养管理平台功能七
一、前言介绍: 1.1 项目摘要 随着社会经济的发展和人们生活水平的提高,越来越多的人开始关注并参与到宠物领养中。宠物已经成为许多家庭的重要成员,人们对于宠物的关爱和照顾也日益增加。然而,传统的宠物领养流程存在诸多不便&a…...
【leetcode hot 100 994】腐烂的橘子
多源广度优先搜索 所有的腐烂橘子在广度优先搜索上是等价于同一层的节点的。假设这些腐烂橘子刚开始是新鲜的,而有一个腐烂橘子(我们令其为超级源点)会在下一秒把这些橘子都变腐烂,而这个腐烂橘子刚开始在的时间是 −1,那么按照广度优先搜索…...
精挑20题:MySQL 8.0高频面试题深度解析——掌握核心知识点、新特性和优化技巧
1. MySQL 8.0 中,为什么查询缓存被移除? 答案: 原因:查询缓存对频繁更新的表效果差,任何对该表的写操作都会清空所有相关缓存,导致缓存命中率低,反而增加开销。 替代方案: 使用应用…...
调研报告:Hadoop 3.x Ozone 全景解析
Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…...
深入理解 RLP 编码与 JSON:原理、应用与比较
在区块链和数据存储领域,RLP(Recursive Length Prefix)编码和**JSON(JavaScript Object Notation)**是两种重要的数据编码方式。它们分别适用于不同的应用场景,并具有不同的优缺点。本文将系统性地分析 RLP…...
【Linux】Makefile秘籍
> 🍃 本系列为Linux的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享🔍 >如果本篇文章有问题,还请多多包涵&a…...
玩转物联网-4G模块如何快速将数据上传到巴法云(TCP篇)
目录 1 前言 2 环境搭建 2.1 硬件准备 2.2 软件准备 2.3 硬件连接 2.4 检查驱动 3 巴法云平台设备创建 3.1 创建账号 3.2 进入巴法云 3.3 获取联网参数 4 连接巴法云 4.1 打开配置工具读取基本信息 4.2 设置连接参数进行数据交互 4.2.1 建立TCP连接 4.2.2 订阅主题 4.2.3 发布信…...
postgresql 高版本pgsql备份在低版本pgsql中恢复失败,报错:“unsupported version”
关键字 PostgreSQL、pg_restore、版本兼容性、数据库迁移、pg_dump、备份恢复、unsupported version in file header 背景环境 系统配置 环境类型操作系统PostgreSQL版本内存工具链测试环境Windows 111616GBNavicat/PgAdmin生产环境Windows Server 2012 R2128GBPgAdmin/命令…...
html相关常用语法
html相关常用语法 HTML(HyperText Markup Language)即超文本标记语言,是用于创建网页的标准标记语言 HTML使用标记语言描述Web页面的结构 HTML元素是HTML页面的建构快 HTML元素通过标签tag来表示 HTML标签是“标题”、”段落“、”表格“等内…...
vue3+ts心得
1、Vue3核心 1、setup setup里弱化this,return可以返回函数,返回后页面也显示那个函数值 data里面是可以用this.来获取setup里的值,这个是单向的 vue3两个script标签不要觉得奇怪,一个是配置组合式api的,一个是配置组…...
单片机flash存储也做磨损均衡
最近在做一个项目,需要保存设置数据,掉电不丢失。那么首先想到的是加个24c02,是一个eeprom,但是客户板太小,没有办法进行扩展。后面就找了一个带ee的OTP单片机,发现擦写次数有限,只有1000次&…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(10)
1.问题描述: 离线推送,锁屏的时候没有弹出消息,只有下拉在通知中心里面显示。请问是否是正常的? 解决方案: 检查一下是否存在图片风控:https://developer.huawei.com/consumer/cn/doc/harmonyos-referen…...
SQLark中如何进行数据筛选与排序
本文将为你介绍在 SQLark 中如何进行数据筛选与排序,掌握这些操作能够极大提升你的工作效率。 SQLark官网链接:www.sqlark.com 数据筛选 在数据库操作中,数据筛选是一项关键功能,它依据特定条件对数据进行过滤,帮助用户从海量数据…...
token升级(考虑在分布式环境中布置token,结合session保证请求调用过程中token不会过期。)
思路: 首先,用户的需求是确保使用同一个Token的外部调用都在一个Session中处理。 需要考虑Token与Session绑定、安全措施、Session管理、分布式处理等。 使用Redis作为Session存储, 在Java中 通过Spring Data Redis或Lettuce库实现。 2.生成…...
VSTO(C#)Excel开发11:自定义任务窗格与多个工作簿
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
python:AI+ music21 构建LSTM模型生成爵士风格音乐
这是一个使用 python的 music21 和 TensorFlow/Keras 构建 LSTM 模型生成爵士风格音乐的完整脚本。该脚本包含MIDI数据处理、模型训练和音乐生成全流程: # -*- coding: utf-8 -*- """AI music21 和 TensorFlow/Keras 构建LSTM模型生成爵士风格音乐 …...
vscode查看文件历史git commit记录
方案一:GitLens 在vscode扩展商店下载GitLens 选中要查看的文件,vscode界面右上角点击GitLens的图标,选择Toggle File Blame 界面显示当前打开文件的所有修改历史记录 鼠标放到某条记录上,可以看到记录详情,选中O…...
使用netDxf扩充LaserGRBL使它支持Dxf文件格式
为 LaserGRBL 扩展支持 DXF 文件格式,需要了解 LaserGRBL 的代码结构,并在其基础上添加 DXF 文件的解析和转换逻辑。以下是详细的扩展方案: 1. 了解 LaserGRBL LaserGRBL 是一个用于控制激光雕刻机的开源软件,支持 G 代码文件的加…...
GaussDB备份数据常用命令
1、常用备份命令gs_dump 说明:是一个服务器端工具,可以在线导出数据库的数据,这些数据包含整个数据库或数据库中指定的对象(如:模式,表,视图等),并且支持导出完整一致的数…...
数学建模 第三节
目录 前言 一 钻井布局问题 第一问分析 第二问分析 总结 前言 这里讲述99年的钻井布局问题,利用这个问题讲述模型优化,LINGO,MATLAB的使用 一 钻井布局问题 这个是钻井布局的原题,坐标的位置为 a [0.50,1.41,3.00,3.37,3…...
单调队列【C/C++】
当我在网上搜索了一大堆单调队列的文章后, 我人傻了!? 单调队列不应该很难吗?? 不应该是,像 优先队列 那样,站在 堆 的肩膀上,极尽升华吗??? …...
Spark DataFrame、Dataset 和 SQL 解析原理深入解析(万字长文多张原理图)
目录 1. Spark SQL 概述 1.1 Spark 整体架构概览 1.2 DataFrame 与 Dataset 简介 2. RDD 与 Spark 的分布式架构基础 2.1 弹性分布式数据集(RDD) 2.2 Spark 的分布式执行模型 3. SQL 解析流程与 Catalyst 优化器 3.1 SQL 解析流程概述 3.2 解析阶段与抽象语法树(AST…...
算法系列——有监督学习——3.逻辑回归
一、概述 逻辑回归是一种学习某个事件发生概率的算法。利用这个概率,可以对某个事件发生或不发生进行二元分类。虽然逻辑回归本来是二元分类的算法,但也可以用于三种类别以上的分类问题。为了理解这个算法,请思考以下例子。 你在回家的路上发…...
