Linux驱动学习笔记(三)

news2025/4/21 12:33:42
并发与竞争

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/。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2319219.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode热题100道——两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…

Git远程拉取和推送配置

Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景:换新电脑后使用Git进行代码拉取和推送过程中,提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次&#xf…

基于SpringBoot+Vue3实现的宠物领养管理平台功能七

一、前言介绍: 1.1 项目摘要 随着社会经济的发展和人们生活水平的提高,越来越多的人开始关注并参与到宠物领养中。宠物已经成为许多家庭的重要成员,人们对于宠物的关爱和照顾也日益增加。然而,传统的宠物领养流程存在诸多不便&a…

调研报告:Hadoop 3.x Ozone 全景解析

Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…

【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 发布信…

vue3+ts心得

1、Vue3核心 1、setup setup里弱化this,return可以返回函数,返回后页面也显示那个函数值 data里面是可以用this.来获取setup里的值,这个是单向的 vue3两个script标签不要觉得奇怪,一个是配置组合式api的,一个是配置组…

SQLark中如何进行数据筛选与排序

本文将为你介绍在 SQLark 中如何进行数据筛选与排序,掌握这些操作能够极大提升你的工作效率。 SQLark官网链接:www.sqlark.com 数据筛选 在数据库操作中,数据筛选是一项关键功能,它依据特定条件对数据进行过滤,帮助用户从海量数据…

VSTO(C#)Excel开发11:自定义任务窗格与多个工作簿

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…

vscode查看文件历史git commit记录

方案一:GitLens 在vscode扩展商店下载GitLens 选中要查看的文件,vscode界面右上角点击GitLens的图标,选择Toggle File Blame 界面显示当前打开文件的所有修改历史记录 鼠标放到某条记录上,可以看到记录详情,选中O…

GaussDB备份数据常用命令

1、常用备份命令gs_dump 说明:是一个服务器端工具,可以在线导出数据库的数据,这些数据包含整个数据库或数据库中指定的对象(如:模式,表,视图等),并且支持导出完整一致的数…

数学建模 第三节

目录 前言 一 钻井布局问题 第一问分析 第二问分析 总结 前言 这里讲述99年的钻井布局问题,利用这个问题讲述模型优化,LINGO,MATLAB的使用 一 钻井布局问题 这个是钻井布局的原题,坐标的位置为 a [0.50,1.41,3.00,3.37,3…

算法系列——有监督学习——3.逻辑回归

一、概述 逻辑回归是一种学习某个事件发生概率的算法。利用这个概率,可以对某个事件发生或不发生进行二元分类。虽然逻辑回归本来是二元分类的算法,但也可以用于三种类别以上的分类问题。为了理解这个算法,请思考以下例子。 你在回家的路上发…

深入理解traceroute命令及其原理

traceroute 是一个网络诊断工具(Windows上叫tracert),用于显示数据包从本地主机到远程主机经过的路由(跳数)。它可以帮助您了解数据包在网络中的传输路径,以及每跳的延迟情况。这对于网络故障排除、分析网络…

前后端联调解决跨域问题的方案

引言 在前后端分离的开发模式中,前端和后端通常在不同的服务器或端口运行,这样就会面临跨域问题。跨域问题是指浏览器因安全限制阻止前端代码访问与当前网页源不同的域、协议或端口的资源。对于 Java 后端应用,我们可以通过配置 CORS&#x…

【vue2 + Cesium】相机视角移动+添加模型、模型点击事件

参考文章:vue2 使用 cesium 【第二篇-相机视角移动添加模型】 这篇文章在上篇文章的基础上继续开发,主要实现效果 相机视角移动 添加模型 点击事件 上篇文章:【vue2 Cesium】使用Cesium、添加第三方地图、去掉商标、Cesium基础配置、地…

【AI】AI编程助手:Cursor、Codeium、GitHub Copilot、Roo Cline、Tabnine

文章目录 一、基本特性对比二、收费标准三、私有部署能力1、Tabnine2、Roo Code 三、代码补全与自然语言生成代码四、安装独立的IDE安装插件安装 五、基本使用(一)Cursor(二)GitHub Copilot1、获取代码建议2.聊天1)上下…

我的uniapp自定义模板

uniapp自定义模板 如有纰漏请谅解,以官方文档为准后面这段时间我会学习小程序开发的知识,会持续更新可以查看我的github,后续我会上传我的uniapp相关练习代码有兴趣的话可以浏览我的个人网站,我会在上面持续更新内容,…

【C++】动态规划从入门到精通

一、动态规划基础概念详解 什么是动态规划 动态规划(Dynamic Programming,DP)是一种通过将复杂问题分解为重叠子问题,并存储子问题解以避免重复计算的优化算法。它适用于具有以下两个关键性质的问题: 最优子结构&…

OpenCV计算摄影学(23)艺术化风格化处理函数stylization()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 风格化的目的是生成不以照片写实为目标的多种多样数字图像效果。边缘感知滤波器是风格化处理的理想选择,因为它们能够弱化低对比度区…