spinlock与linux内核调度的关系

作者:刘洪涛,华清远见嵌入式学院高级讲师,ARM公司授权ATC讲师。

  关于自旋锁用法介绍的文章,已经有很多,但有些细节的地方点的还不够透。我这里就把我个人认为大家容易有疑问的地方拿出来讨论一下。

  一、自旋锁(spinlock)简介

  自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点可以应用在多处理机器、或运行在单处理器上的抢占式内核中需要的锁定服务。

  二、信号量简介

  这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。

Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。

  三、自旋锁和信号量对比

  在很多地方自旋锁和信号量可以选择任何一个使用,但也有一些地方只能选择某一种。下面对比一些两者的用法。

  表1-1自旋锁和信号量对比

应用场合

信号量or自旋锁

低开销加锁(临界区执行时间较快)

优先选择自旋锁

低开销加锁(临界区执行时间较长)

优先选择信号量

临界区可能包含引起睡眠的代码

不能选自旋锁,可以选择信号量

临界区位于非进程上下文时,此时不能睡眠

优先选择自旋锁,即使选择信号量也只能用down_trylock非阻塞的方式

四、自旋锁与linux内核进程调度关系

我们讨论下表1-1中的第3种情况(其它几种情况比较好理解),如果临界区可能包含引起睡眠的代码则不能使用自旋锁,否则可能引起死锁。

那么为什么信号量保护的代码可以睡眠而自旋锁就不能呢?

先看下自旋锁的实现方法吧,自旋锁的基本形式如下:

spin_lock(&mr_lock);

//临界区

spin_unlock(&mr_lock);

跟踪一下spin_lock(&mr_lock)的实现

#define spin_lock(lock)  _spin_lock(lock)

#define _spin_lock(lock)      __LOCK(lock)

#define __LOCK(lock) \

do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

注意到“preempt_disable()”,这个调用的功能是“关抢占”(在spin_unlock中会重新开启抢占功能)。从中可以看出,使用自旋锁保护的区域是工作在非抢占的状态;即使获取不到锁,在“自旋”状态也是禁止抢占的。了解到这,我想咱们应该能够理解为何自旋锁保护的代码不能睡眠了。试想一下,如果在自旋锁保护的代码中间睡眠,此时发生进程调度,则可能另外一个进程会再次调用spinlock保护的这段代码。而我们现在知道了即使在获取不到锁的“自旋”状态,也是禁止抢占的,而“自旋”又是动态的,不会再睡眠了,也就是说在这个处理器上不会再有进程调度发生了,那么死锁自然就发生了。

咱们可以总结下自旋锁的特点:

●  单处理器非抢占内核下:自旋锁会在编译时被忽略;

●  单处理器抢占内核下:自旋锁仅仅当作一个设置内核抢占的开关;

●  多处理器下:此时才能完全发挥出自旋锁的作用,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。

五、linux抢占发生的时间

最后在了解下linux抢占发生的时间,抢占分为用户抢占和内核抢占。

用户抢占在以下情况下产生:

●  从系统调用返回用户空间

●  从中断处理程序返回用户空间

内核抢占会发生在:

●  当从中断处理程序返回内核空间的时候,且当时内核具有可抢占性;

●  当内核代码再一次具有可抢占性的时候。(如:spin_unlock时)

●  如果内核中的任务显式的调用schedule()

●  如果内核中的任务阻塞。

基本的进程调度就是发生在时钟中断后,并且发现进程的时间片已经使用完了,则发生进程抢占。通常我们会利用中断处理程序返回内核空间的时候可以进行内核抢占这个特性来提高一些I/O操作的实时性,如:当I/O事件发生的是时候,对应的中断处理程序被激活,当它发现有进程在等待这个I/O事件的时候,它会激活等待进程,并且设置当前正在执行进程的need_resched标志,这样在中断处理程序返回的时候,调度程序被激活,原来在等待I/O事件的进程(很可能)获得执行权,从而保证了对I/O事件的相对快速响应(毫秒级)。可以看出,在I/O事件发生的时候,I/O事件的处理进程会抢占当前进程,系统的响应速度与调度时间片的长度无关。

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

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

相关文章

Python参数类型

位置参数默认参数可变参数命名关键字参数关键字参数1 def position_only(a, b):2 print(a, b)3 4 def keyword(aa, bb):5 print(a, b)6 7 def arg(a, *args):8 print(a, args)9 10 def kw(a, **kwargs): 11 print(a, kwargs) 12 13 def many1(a, b, cc, *arg…

keil用c语言怎么编辑器,用keil软件编写单片机程序的步骤

猜你感兴趣:新手教程:单片机的学习实践步骤运用单片机便是了解单片机硬件结构,以及内部资源的运用,在汇编或C语言中学会各种功用的初始化设置,以及完成各种功用的程序编制。 运用按钮输入信号,发光二极管显…

24c语言程序设计是啥,《C语言程序设计》作业答案.docx

精心整理《 C 语言程序设计》作业答案1.第 4题以下程序的输出结果是______。main(){intn[3][3],i,j;精心整理for(i0;ifor(j0;jfor(i0;ifor(j0;j)n[i1][j1]n[i][j];printf("%d\n",n[i][j]);---来源网络,仅供分享学习2/145精心整理}A.14B.0C.6D.…

体重 年龄 性别 身高 预测鞋码_【新手扫盲】身高体重性别年龄身体素质影响玩滑板吗?...

很多新手在迈入滑板大门之前都会有诸多顾虑,以为滑板跟其他运动一样,门槛很高我想说,滑板是项自由友好的运动下到3岁小宝宝,上到60岁以上老人只要你想玩,那就可以参与进来没有任何因素能阻止你玩滑板1、你比他高吗&…

c语言读入文件排序,帮忙-如何对文件排序啊

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼楼主加分哦,看看吧#include #include //#include #include #include using namespace std;void dfsFolder(string folderPath){ _finddata_t FileInfo; string strfind folderPath "\\*.*"; long Handle _…

html5点击按钮出现弹窗 怎么实现_HTML5游戏开发过程中的二三事

文/ Luiu最近跟的一款项目是HTML5手游,在这个项目中遇到并解决了诸多问题,也学习到了很多项目开发过程中需要注意的事情。这个项目自立项到现在已经过了5个多月,如今项目研发已经过了早期的忙乱阶段,于是借此机会梳理下思绪&#…

HDU 2063 过山车【二分图最大匹配】

Problem DescriptionRPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有…

c语言编写贪吃蛇代码无错,刚学C语言,想写一个贪吃蛇的代码

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include#include#include#includetypedef struct snake{int a;int b;struct snake *u;struct snake *n;}snake,*snake1;typedef struct food{int a;int b;}food;void main(){char c,c0 d;int i,j,k,n1,t,at;snake p,q;snake *dd,…

blockchain_eth客户端安装 geth使用 批量转账(二)

回顾一下,前面我们讲到启动geth geth --rpc --datadir "F:/geth/Geth/" --light console 2>console.log 这一篇接着上面讲geth的使用,分为4个部分 1、创建账户 2、验证区块是否更新完毕 3、解锁账户 4、转账 此时进入到命令行模式 1、首先&…

CGContextAddLines和CGContextAddLineToPoint在线条半透明时候的区别

这两种都可以用来画线&#xff0c;前一种将整条线加入后画出&#xff0c;后一种对每个点进行和前一个点的连线。 sample1-(void)drawLine:(YJLines *)line{ int count [line.points count]; CGPoint addLines[count]; for (int j0; j< [line.points count]; j) { CGPoint …

android xml获取指定,android:如何从xml文件中获取信息?

我得到一个程序&#xff0c;从一个链接的服务器获取天气。我已经做了一些将字符串结合到URL的字符串。我现在需要从XML文件中获取信息。android&#xff1a;如何从xml文件中获取信息&#xff1f;这是我的代码&#xff1a;(我更换了&#xff0c;为了安全起见API KEY)package com…

科研入门之在web of science

ISI Web of Science是全球最大、覆盖学科最多的综合性学术信息资源&#xff0c;收录了自然科学、工程技术、生物医学等各个研究领域最具影响力的超过8700多种核心学术期刊。利用Web of Science丰富而强大的检索功能-普通检索、被引文献检索、化学结构检索&#xff0c;可以方便快…

手动生成 XML

2019独角兽企业重金招聘Python工程师标准>>> private void Button1_Click(object sender, System.EventArgs e) { //创建新的xml XmlDocument doc new XmlDocument(); doc.LoadXml("<company></company>"); //设置版本信息 XmlDeclaration x…

android 资源如何下沉,个推安卓手机报告: 华为一路领跑,OV下沉市场表现不俗

近日&#xff0c;国内专业的数据智能服务商个推(股票代码&#xff1a;每日互动 300766.sz)发布《 2019 年度安卓智能手机报告》&#xff0c;对华为、小米、OPPO、vivo、三星等国内主要智能手机品牌进行盘点。数据显示&#xff0c;华为手机 2019 年表现不俗&#xff0c;不仅以25…

序列化shelve模块

1.shelve对pickle进行封装&#xff0c;所以shelve也只能在python里使用。 shelve可以进行多次dump而且顺序不会乱。 import shelvef shelve.open(shelve_test) #打开文件方式和json&#xff0c;pickle不同。names [li,xiao,xiao,ali,lucas] dicts {lucy:1,liming:2,casio…

for循环执行 mybatis_mybatis sql循环的使用

foreach的主要用在构建in条件中&#xff0c;它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有 item&#xff0c;index&#xff0c;collection&#xff0c;open&#xff0c;separator&#xff0c;close。item表示集合中每一个元素进行迭代时的别名&#xff0c;index…

jQuery EasyUI API 中文文档 - 微调器(Spinner)

Spinner 微调器扩展自 $.fn.validatebox.defaults&#xff0c;用 $.fn.spinner.defaults 重写了 defaults。依赖validatebox用法1. <input id"ss" value"2"> 1. $(#ss).spinner({ 2. required:true, 3. increment:10 4. }); 特性其特…

android reboot 定时重启可靠吗,请教一下有人做过安卓系统 reboot 重启之后,appium 能自动重新连接吗...

就是我用 adb 的命令重启手机&#xff0c;然后 usb 是一直连着的&#xff0c;重启之后&#xff0c;我想做尝试能让 appium 自动重新连接尝试过先让driver.quit(); //driver 先退出Thread.sleep(40000)&#xff1b;线程等待&#xff0c;但是还没到 40 秒就报错了org.openqa.sele…

python常用功能_python----常用功能

sintance和typeclass Foo(object):passclass Bar(Foo):passobj Bar()# isinstance用于判断&#xff0c;对象是否是指定类的实例 (错误的)# isinstance用于判断&#xff0c;对象是否是指定类或其派生类的实例# isinstance不精准print(isinstance(obj,Foo),id(obj)) #True 35558…

Flask学习目录

目录 Flask学习初识 Flask学习二 转载于:https://www.cnblogs.com/xiaogongzi/p/8868443.html