linux内核中竞态的解决方法

这篇具有很好参考价值的文章主要介绍了linux内核中竞态的解决方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、内核中竞态的产生原因

表面原因

  • 多个进程同时访问同一个驱动资源时,造成了资源的争抢,这个就是竞态

本质原因

  • 对于单核处理器,支持资源抢占,那么就会出现竞态
  • 对于多核处理器,核与核之间本身就会存在竞态
  • 对于中断和进程,也存在竞态
  • 中断和中断之间,如果支持中断嵌套(一个中断正在执行,另一个优先级高的中断来了),那么就会出现竞态,不支持中断嵌套则没有竞态

2、竞态的解决方法

2.1中断屏蔽

概述

对于单核处理器,中断和进程会产生竞态,为了解决这个竞态,可以在进程访问临界资源时让中断不启用。但是如果长时间不启用中断就会对整个系统产生不利的影响,严重是甚至会导致系统崩溃。所以使用中断屏蔽时要求屏蔽中断的时间尽可能短。(NS),中断屏蔽一般是内核开发者进行调试时使用。

API

//屏蔽中断
local_irq_disable();
临界资源
//中断使能
local_irq_enable();

2.2自旋锁(盲等锁)

概述

内核专门为多核CPU设计

一个进程访问临界资源时使用自旋锁对进程上锁,另一个进程也想访问,但是解不开锁,此时这个进程进入自旋状态(盲等状态)

特点

  • 处于自旋状态下的进程是运行态,需要消耗CPU资源
  • 自旋锁锁住的临界资源要求临界资源的体积小,而且临界资源中不可以有延时、耗时甚至休眠的操作,也不可以有copy_to_user()和copy_from_user()
  • 自旋锁会出现死锁
  • 自旋锁可以用于进程访问临界资源时,也可以用于中断访问临界资源
  • 自旋锁上锁后会关闭抢占

API

//定义一个自旋锁
spinlock_t lock;
//初始化自旋锁
spin_lock_init(&lock);  
//上锁
void spin_lock(spinlock_t *lock)
//解锁
void spin_unlock(spinlock_t *lock)

2.3信号量

概述

进程在访问临界资源之前先去申请信号量,如果申请到了就访问,申请不到,此时进程切换到休眠状态

特点

  • 申请不到信号量的进程切换到休眠状态,休眠状态不消耗CPU资源,但是状态切换的过程需要消耗CPU资源
  • 信号量保护的临界区可以很大,里面也可以有延时、耗时甚至休眠的操作
  • 信号量只能用于进程上下文,不能用于中断上下文
  • 信号量不会出现死锁
  • 信号量也不会关闭抢占

API

1.定义信号量
struct semaphore sema;
2.初始化信号量
void sema_init(struct semaphore *sem, int val)
参数:
sem:定义的信号量首地址
val:初始化信号量数值,这里初始化为1
返回值:无
3.void down(struct semaphore *sem);
功能:申请信号量

4.void up(struct semaphore *sem);
功能:释放信号量

2.4互斥体

概述

一个进程访问临界资源之前先获取互斥体,如果获取不到,进程不能访问临界资源,此时进程切换到休眠状态

特点

  • 申请不到互斥体的进程切换到休眠状态,休眠状态不消耗CPU资源,但是状态切换的过程需要消耗CPU资源
  • 互斥体保护的临界区可以很大,里面也可以有延时、耗时甚至休眠的操作
  • 互斥体只能用于进程上下文,不能用于中断上下文
  • 互斥体不会出现死锁
  • 互斥体也不会关闭抢占
  • 和信号量不同的是,如果将进程获取不到互斥体,进程不会立即进入休眠,而是等待一段时间,这个时间期间如果获取到互斥体,进程可以不用休眠。所以互斥体的效率要比信号量高

API

1.定义互斥体
struct mutex mutex;
2.初始化互斥体
mutex_init(&mutex);
3.获取互斥体
void mutex_lock(struct mutex *lock);
4.释放互斥体
void mutex_unlock(struct mutex *lock);

2.5原子操作

概述

将进程访问临界资源的过程看作一个不可分割的原子状态。当进程访问完临界资源后,原子状态被打破。另一个进程可以访问临界资源,原子操作是通过对原子变量的数值修改来实现的,原子变量数值的修改又依赖于内联汇编实现。文章来源地址https://www.toymoban.com/news/detail-622393.html

API

1.定义原子变量并初始化
atmoic_t atm=ATOMIC_INIT(1);//解决竞态时只有1和-1两种值;除这俩之外还有计时的作用
2.
int atomic_dec_and_test(atomic_t *v)
功能:原子变量的数值-1并且拿结果和0比较
参数:
    v:原子变量的首地址
返回值:
如果原子变量数值-1后结果为0,则返回真,否则返回假

3.void atomic_inc(atomic_t *v)
功能:原子变量的数值+1
************************************
1.定义原子变量并初始化
atmoic_t atm=ATOMIC_INIT(-1);
2.
int atomic_inc_and_test(atomic_t *v)
功能:原子变量的数值+1并且拿结果和0比较
参数:
    v:原子变量的首地址
返回值:
如果原子变量数值+1后结果为0,则返回真,否则返回假

3.void atomic_dec(atomic_t *v)
功能:原子变量的数值-1

到了这里,关于linux内核中竞态的解决方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】基础知识 第六课 内核 & 架构

    4 个主动单元 + 4 个被动单元 主动单元 被动单元 Cortex M3 内核 DCode 总线 (D-Bus) 内部 FLASH Cortex M3 内核系统总线 (S-Bus) 内部 SRAM 通用 DMA1 FSMC 通用 DMA2 AHB 到 APB 的桥, 它连接的所有 APB 外设 AHB (Advance High-performance Bus): 高级高性能总线 APB (Advance Peripheral Bus): 高级外围总线 ICode 总线

    2023年04月24日
    浏览(55)
  • STM32中BOOT的作用 (芯片死锁解决方法)

    stm32中具有BOOT1和BOOT0 BOOT是stm32单片机的启动模式, 通过不同组合模式,共有三种启动方式。 一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。 第一种方式(boot

    2024年02月11日
    浏览(24)
  • STM32芯片连接电脑出现的问题与解决方法

    我用的是正点原子STM32F1系列芯片,在用FLYMCU烧录程序时出现不少问题,下面是我列举的问题和解决方法。 1.FLYMCU参数设置 ①DTR低电平复位,RTS高电平进BootLoader ②勾选:校验、编程后执行、编程后重装文件 ③波特率:F1系列芯片可设置为115200 2.FLYMCU连接不上芯片,显示连接超

    2024年04月23日
    浏览(36)
  • [分享]STM32G070 串口 乱码 解决方法

    NUCLEO-G070RB cubemx 7bit 改为 8bit   #include stdio.h      

    2024年02月13日
    浏览(27)
  • 一种解决STM32多串口同时收发的方法

    在做项目中,遇到了同时调用串口通信时程序崩溃的问题,在项目中,串口1用作调试串口,串口2用作MQTT通信串口,串口3用作下位机通信串口, 串口1重定向以后,用库函数自带的printf函数打印字符串 串口2使用自己写的u2_printf函数,即va_list这套变参宏定义后使用vsprintf函数

    2023年04月21日
    浏览(28)
  • STM32CubeIDE更新ST LINK驱动失败解决方法

    当使用CubeIDE下载程序时,在这里遇到个STM32CubeIDE需要ST Link更新的提示 弹出 “in order to use the attached ST-LINK with this version of STM32CubeIDE an update of the ST LINK firmware is required” “为了将连接的ST-LINK与此版本的STM32CubeIDE一起使用,需要更新ST-LINK固件” 但是使用Cube更新失败的情况,

    2024年02月16日
    浏览(31)
  • 在学习STM32出现“ no target connected ”的解决方法

    1、接线问题导致 在编译内容后,点击LOAD时显示“ no target connected ”,再网上找办法时说是因为ST-Link版本问题需要进行更新,更新完成后发现还是出现“ no target connected ”,后来经过仔细检查发现是我的STM32和ST-Link的线接错了 正确接线如下图所示: 接线正确后,即可成功下

    2024年02月07日
    浏览(36)
  • STM32CubeIDE串口printf函数输出中文乱码(配置教程+解决方法)

    目录 前言 平台环境 软件:STM32CubeIDE 硬件:STM32H7A3ZIT6Q 一、串口配置 二、printf重定向 三、中文乱码解决方案 步骤 效果 四、总结 本文主要讲述在使用CubeIDE配置串口通信的过程中,如何 重定向printf() 函数,以及如何解决在 串口打印中文时输出乱码 的情况。         

    2024年02月07日
    浏览(34)
  • STM32使用SPI通信时的一些常见问题及解决方法(主,从)

            最近在做一个多MCU的项目时,MCU之间的数据传输使用了SPI通信,在做从机时遇到了一些 “疑难杂症”,研究了半天,总算是把故障排除了,就又总结了一下SPI常遇到的几种问题写出来整理一下。 目录 一、SPI简介:  二、常见问题: 三、疑难杂症: Q1:使用的HAL库,

    2024年02月21日
    浏览(46)
  • 关于在keil官网下载STM32芯片包速度很慢的解决方法。

    关于在keil官网下载STM32芯片包速度很慢的解决方法。 1、打开以下网址:https://www.keil.com/dd2/pack/#!#eula-container 2、首先要确定好你所需要的芯片是哪一系列的。 3、下载个迅雷。 4、创建一个文本,复制以下网址。 http://keilpack.azureedge.net/pack/ 5、参考以下操作 http://keilpack.azureed

    2024年02月13日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包