linux驱动 自旋锁

最近在内核频繁使用了自旋锁,自旋锁如果使用不当,极易引起死锁,在此总结一下。

自旋锁是一个互斥设备,它只有两个值:“锁定”和“解锁”。它通常实现为某个整数值中的某个位。希望获得某个特定锁得代码测试相关的位。如果锁可用,则“锁定”被设置,而代码继续进入临界区;相反,如果锁被其他人获得,则代码进入忙循环(而不是休眠,这也是自旋锁和一般锁的区别)并重复检查这个锁,直到该锁可用为止,这就是自旋的过程。“测试并设置位”的操作必须是原子的,这样,即使多个线程在给定时间自旋,也只有一个线程可获得该锁。

自旋锁最初是为了在多处理器系统(SMP)使用而设计的,但是只要考虑到并发问题,单处理器在运行可抢占内核时其行为就类似于SMP。因此,自旋锁对于SMP和单处理器可抢占内核都适用。可以想象,当一个处理器处于自旋状态时,它做不了任何有用的工作,因此自旋锁对于单处理器不可抢占内核没有意义,实际上,非抢占式的单处理器系统上自旋锁被实现为空操作,不做任何事情。

自旋锁有几个重要的特性:1、被自旋锁保护的临界区代码执行时不能进入休眠。2、被自旋锁保护的临界区代码执行时是不能被被其他中断中断。3、被自旋锁保护的临界区代码执行时,内核不能被抢占。从这几个特性可以归纳出一个共性:被自旋锁保护的临界区代码执行时,它不能因为任何原因放弃处理器

考虑上面第一种情况,想象你的内核代码请求到一个自旋锁并且在它的临界区里做它的事情,在中间某处,你的代码失去了处理器。或许它已调用了一个函数(copy_from_user,假设)使进程进入睡眠。也或许,内核抢占发威,一个更高优先级的进程将你的代码推到了一边。此时,正好某个别的线程想获取同一个锁,如果这个线程运行在和你的内核代码不同的处理器上(幸运的情况),那么它可能要自旋等待一段时间(可能很长),当你的代码从休眠中唤醒或者重新得到处理器并释放锁,它就能得到锁。而最坏的情况是,那个想获取锁得线程刚好和你的代码运行在同一个处理器上,这时它将一直持有CPU进行自旋操作,而你的代码是永远不可能有任何机会来获得CPU释放这个锁了,这就是悲催的死锁

考虑上面第二种情况,和上面第一种情况类似。假设我们的驱动程序正在运行,并且已经获取了一个自旋锁,这个锁控制着对设备的访问。在拥有这个锁得时候,设备产生了一个中断,它导致中断处理例程被调用,而中断处理例程在访问设备之前,也要获得这个锁。当中断处理例程和我们的驱动程序代码在同一个处理器上运行时,由于中断处理例程持有CPU不断自旋,我们的代码将得不到机会释放锁,这也将导致死锁。

因此,如果我们有一个自旋锁,它可以被运行在(硬件或软件)中断上下文中的代码获得,则必须使用某个禁用中断的spin_lock形式的锁来禁用本地中断(注意,只是禁用本地CPU的中断,不能禁用别的处理器的中断),使用其他的锁定函数迟早会导致系统死锁(导致死锁的时间可能不定,但是发生上述死锁情况的概率肯定是有的,看处理器怎么调度了)。如果我们不会在硬中断处理例程中访问自旋锁,但可能在软中断(例如,以tasklet的形式运行的代码)中访问,则应该使用spin_lock_bh,以便在安全避免死锁的同时还能服务硬件中断。

补充:

锁定一个自旋锁的函数有四个:

void spin_lock(spinlock_t *lock);      

最基本得自旋锁函数,它不失效本地中断。

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

在获得自旋锁之前禁用硬中断(只在本地处理器上),而先前的中断状态保存在flags中

void spin_lockirq(spinlock_t *lock);

在获得自旋锁之前禁用硬中断(只在本地处理器上),不保存中断状态

void spin_lock_bh(spinlock_t *lock);

在获得锁前禁用软中断,保持硬中断打开状态


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

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

相关文章

百度输入法

[用户界面]:界面美观,有不同画风的ui界面,适合不同消费群体的需求。 [记住用户选择]:会默认记住用户以往的输入习惯,只需输入首拼音字母就会出现过去使用的高频词。 [短期刺激]:美化的用户界面让人眼前一新…

rs232读取智能电表_三相电表怎么看度数 怎么计算总电量

现在的三相电表一般都是在屏幕上面直接看,屏幕上面是有文字提示显示的,三相电表的总度数,上面的文字提醒一般是“正向有功总电量”,三相电表一般屏幕旁边都会上翻键和下翻键,可以上下翻开电表里面的数据。如下图所示&a…

android 学习随笔十六(广播 )

1、广播接收者 BroadcastReceiver接收系统发出的广播现实中的广播:电台为了传达一些消息,而发送的广播,通过广播携带要传达的消息,群众只要买一个收音机,就可以收到广播了 Android中的广播:系统在运行过程中…

驱动面试题总结

1、字符型驱动设备你是怎么创建设备文件的,就是/dev/下面的设备文件,供上层应用程序打开使用的文件? 答:mknod命令结合设备的主设备号和次设备号,可创建一个设备文件。 评:这只是其中一种方式&#xff0…

python程序写诗_将Python诗歌与D结合起来

在与docker一起使用poetry时,需要记住以下几点。 安装 安装poetry的正式方法是通过:curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python 这种方式允许poetry及其依赖项与依赖项分离。但是,在我看来…

Azure运维系列 4:安装和使用Azure PowerShell管理云

前面讲到了很多的管理方式,包括Azure中国最近更新的预览版管理门户和Azure云助理,都是非常不错的管理Azure的方式,今天我们再来介绍一种更加高效的管理方式Azure PowerShell。熟悉命令行的朋友都知道,Linux之所以那么好用是因为其…

[转]char * 和字符数组

[转]char * 和字符数组 原文地址:http://www.cnblogs.com/jeakon/archive/2012/05/27/2816809.html 代码中的int * i就是我们关注的焦点。它是一个指向int指针。也就是说:i指向一个内存地址,从这个地址开始存储了一个数据。int * i中的int标明…

设备模型1

作为开头篇,我不想写HELLLOWORLD驱动,甚至字符设备驱动的开发,这样文章充斥在各大网站上的博客上,随便搜搜,就可以找到几百篇。这是最基本的东西,通过这些内容的学习,我们要掌握LINUX驱动的基本…

如何使用Android Studio把自己的Android library分享到jCenter和Maven Central

第一部分:在bintray上创建package首先,你需要在bintray上创建一个package。为此,你需要一个bintray账号,并在网站上创建一个package。第一步:在bintray.com上注册一个账号。(注册过程很简单,自己…

python2编码_Python2字符编码

我们通常见到的字符串编码主要是三种GB2312/GBK、Unicode、UTF-8。GB2312/GBK是多字节(multibytes)编码的一种,属于“ASCII的加强版”,与之平行的由Big5、ShiftJIS之类的编码各自为政,所有这些用两个字节表示汉字的多字节编码标准统称为ANSI编…

angularJs关于指令的一些冷门属性

我们使用ng的时候,经常会使用到指令,大家所熟知的属性我在这里就不介绍了,讲讲大家没怎么留意的属性 1.multiElement 这是指定指令作用区间的功能,最常用的就是ng-repeat-start和ng-repeat-end了。 2.priority 指令优先级&#xf…

设备模型2

前言 在上一篇中,我们大致描述了LINUX设备模型,我们先来总结一下三要素的关系。 从图中可以看出,Linux设备模型就是"总线、设备、驱动、类"这四个概念之前的相互关系;这也是Linux2.6内核抽象出来的用于管理系统中所有设备的模型图; 简单地描述…

angular自定义指令详解

指令(directive)是angular里面最核心也是最难懂的东西,在慕课网看了下大漠穷秋老湿的视频,自己百度半天做了一些小test,总算把一切都搞明白了。 先列出学习来源: 指令中controller和link的区别:…

delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨

多次被问到这样的问题:java服务端的rsa加密操作已经完成,返回一个16进制的字符串给python平台,但是在python进行私钥解密的时候发现行不通。。。。前端python加密,后端用java解密,解不出来还有诸如nodejs从理论上来说&…

类的定义、成员定义修饰符

类的定义 修饰符含义1无或internal 只能在当前项目中访问类,其它项目引用后也无法访问2public 可以任何地方访问类3abstract 不能实例化,只能供继承之用4sealed 不能供派生之用,只能实例化5internal abstract136public abstract237intern…

设备模型3

在上一篇分析中,多次提到了SYSFS,这是个什么东西?这可是个很大的TOPIC,关于它的讲述可以写本书,但是我们暂时的目标不是要完全啃投它所有的东西,没时间,没精力,我们只要掌握我们需要…

浪潮之巅读后感

这几天看到一本非常好的书《浪潮之巅》。浪潮,指的是时代的大潮。而浪潮之巅,顾名思义就是指站在时代潮流的巅峰,引领时代潮流,扛起发展大旗。而本书就是在介绍各大处在浪潮之巅的IT公司的历史及发展。 书中有句话说得好&#xff…

利用dft的定义计算dft的matlab程序_CP2K教程系列之静态计算(Pymatflow篇)

本系列CP2K教程是《CP2K菜根谭》的升级版,在旧版基础上添加了如何结合Pymatflow工具简化计算流程的内容。话不多说,本文将为您带来CP2K系列教程中的静态计算部分。静态计算设置静态计算是大多数人接触第一性原理计算后第一次运行的计算类型。很多其它类型…

机器学习:最大似然估计与最大后验概率估计

在机器学习领域,概率估计是经常用到的一种模型,而概率估计中,我们经常会看到两种估计模型,一种是最大似然估计,即 Maximum likelihood, 另外一种就是最大后验概率估计,即 Maximum posterior &am…

ubuntu14.04安装git

参考教程:git介绍:安装,使用,创建分支 安装的方法有两种,一种直接是通过ubuntu的APT安装,这种方法最简便,缺点是版本可能不是最新的。所有还有另一种方法是下载源码进行安装,这种能…