一、概括

(1)自旋锁适用于SMP系统,UP系统用spinlock是作死。

(2)保护模式下禁止内核抢占的方法:1、运行终端服务例程时2、运行软中断和tasklet时3、设置本地CPU计数器preempt_count

(3)自旋锁的忙等待的实际意义是:尝试获取自旋锁的还有一个进程不断尝试获取被占用的自旋锁,中间仅仅pause一下!

(4)在抢占式内核的spin_lock宏中,第一次关抢占,目的是防止死锁(防止一个已经获取自旋锁而未释放的进程被抢占!

)。

而后又开抢占。目的是让已经释放自旋锁的进程能够被调度出去,让其它进程能够进入临界区。当然,开启内核抢占后,调度器调度的进程是不是在盲等的进程不可而知!

二、具有内核抢占的spin_lock宏

让我们来具体讨论用于请求自旋锁的spin_lock宏。以下的描写叙述都是针对支持SMP系统的抢占式内核的。

该宏获取自旋锁的地址sip作为它的參数,并运行以下的操作:

调用preempt_disable()以禁用内核抢占

调用函数__raw_spin_trylock()。它对自旋锁的slock字段运行原子性的測试和设置操作。

该操作首先运行等价于下列汇编片段的一些指令:

movb$0,%a1

xchgb%al,slp->slock

汇编语言指令xchg原子性地交换8位寄存器%al和slp->slock指示的内存单元的内容。

随后,假设存放在自旋锁中的旧值是正数,函数就返回1,否则返回0。

假设自旋锁中的旧值是正数,宏结束;内核控制路径已经获得自旋锁。

否则,内核控制路径无法获得自旋锁。因此宏必须运行循环一直到在其他CPU上运行的内核控制路径释放自旋锁。调用preempt_enable()递减在第1步递增了的抢占计数器。假设在运行spin_lock宏之前内核抢占被启用,那么其他进程此时能够代替等待自旋锁的进程。

假设break_lock字段等于0。则把它设置为1。通过检測该字段,拥有锁并在其他CPU上执行的进程能够知道是否有其他进程在等待这个锁。假设进程把持某个自旋锁的时间太长。它能够提前释放锁以便等待同样自旋锁的进程能够继续向前执行。

运行等待循环:

while(spin_is_locked(sip)&& slp->break_lock)

cpu_relax();

宏cpu_relax()简化为一条pause汇编语言指令。

在Pentium4模型中引入了这条指令以优化自旋锁循环的运行。

通过引入一个非常短的延迟。加快了紧跟在锁后面的代码的运行并降低了能源消耗。pause与早先的80x86微处理器模型是向后兼容的。由于它相应rep;nop指令,也就是相应空操作。

跳转回第1步,再次试图获取自旋锁

三、非抢占式内核中的spin_lock宏

假设在内核编译时没有选择内核抢占选项,spin_lock宏就与前面描写叙述的spin_lock宏有非常大的差别。在这样的情况下,宏生成一个汇编语言程序片段,它本质上等价于以下紧凑的忙等待:

1:lock;decbslp->lock

jns3f

2:pause

cmpb$0,slp->slock

jle2b

jmp1b

3;

汇编语言指令decb递减自旋锁的值,该指令是原子的,由于它带有lock字节前缀。随后检測符号标志,假设它被清0,说明自旋锁被设置为1,因此从标记3处继续正常运行。否则。在标签2处运行紧凑循环直到自旋锁出现正值。然后从标签1处開始又一次运行。由于不检查其他的处理器是否抢占了锁就继续运行是不安全的。

spin_unlock宏

spin_unlock宏释放曾经获得的自旋锁,它本质上运行下列汇编语言指令;

movb$1,slp->slock

并在随后调用preempt_enable(),注意,由于如今的80x86微处理器总是原子地运行内存中的仅仅写訪问,所以不使用lock字节。

抢占式内核与非抢占式内核中的自旋锁(spinlock)的差别的更多相关文章

  1. Java IO:同步、非堵塞式IO(NIO)

    转载请注明出处:jiq•钦's technical Blog 引言 JDK1.4中引入了NIO,即New IO,目的在于提高IO速度.特别注意JavaNIO不全然是非堵塞式IO(No-Blocking ...

  2. 为什么IO多路复用需要采用非阻塞式IO

    近段时间开始学习<Unix网络编程>,代码实现了一个简单的IO多路复用+阻塞式的服务端,在学习了非阻塞式IO后,有一个疑问,即: 假如调用了select,并且关注了几个描述字,当关注的描述 ...

  3. 并发式IO的解决方案:多路非阻塞式IO、多路复用、异步IO

    在Linux应用编程中的并发式IO的三种解决方案是: (1) 多路非阻塞式IO (2) 多路复用 (3) 异步IO 以下代码将以操作鼠标和键盘为实例来演示. 1. 多路非阻塞式IO 多路非阻塞式IO访 ...

  4. Spring学习(1):侵入式与非侵入式,轻量级与重量级

    一. 引言 在阅读spring相关资料,都会提到Spring是非侵入式编程模型,轻量级框架,那么就有必要了解下这些概念. 二. 侵入式与非侵入式 非侵入式:使用一个新的技术不会或者基本不改变原有代码结 ...

  5. linux内核--自旋锁的理解

    http://blog.chinaunix.net/uid-20543672-id-3252604.html 自旋锁:如果内核配置为SMP系统,自旋锁就按SMP系统上的要求来实现真正的自旋等待,但是对 ...

  6. Linux内核的同步机制---自旋锁

    自旋锁的思考:http://bbs.chinaunix.net/thread-2333160-1-1.html 近期在看宋宝华的<设备驱动开发具体解释>第二版.看到自旋锁的部分,有些疑惑. ...

  7. Linux内核同步:自旋锁

    linux内核--自旋锁的理解 自旋锁:如果内核配置为SMP系统,自旋锁就按SMP系统上的要求来实现真正的自旋等待,但是对于UP系统,自旋锁仅做抢占和中断操作,没有实现真正的“自旋”.如果配置了CON ...

  8. Linux 2.6内核中新的锁机制--RCU

    转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...

  9. Linux 内核同步之自旋锁与信号量的异同【转】

    转自:http://blog.csdn.net/liuxd3000/article/details/8567070 Linux 设备驱动中必须解决的一个问题是多个进程对共享资源的并发访问,并发访问会导 ...

随机推荐

  1. 数据结构之线性顺序表ArrayList(Java实现)

    一.ListMe接口: import java.util.ArrayList; //实现线性表(顺序表和链表)的接口://提供add get isEmpty size 功能public interfa ...

  2. OBJECTPROPERTY用法整理

    OBJECTPROPERTY用法整理 分类: 系统表与表结构 数据库管理维护2010-06-03 16:37 2783人阅读 评论(1) 收藏 举报 数据库sql serverinsertobject ...

  3. 3D超炫酷旋转

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. 用PHP的GD库画五星红旗来玩玩

    1 header("Content-Type:image/jpeg"); $img=imagecreatetruecolor(999,667); $color=imagecolor ...

  5. [Python3网络爬虫开发实战] 7.1-Selenium的使用

    Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击.下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬.对于一些JavaScript动态渲染的页面来说 ...

  6. Python之条件判断

    Python之条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age ...

  7. Python之使用eval()函数将字符串的数据结构提取出来

    data = input('请输入你要修改的对象:').strip() ''' 输入下面的字典列表 [{'backend':'www.oldboy1.org','record':{'server':' ...

  8. js 循环 js创建数组

    循环 for (var i = 0; i < myArray.length; i++) { console.log(myArray[i]); }; for (var arr in myArray ...

  9. Altium designer中生成gerbera文件

    在Altium designer中生成gerbera文件的方法有很多,不同版本,差异行不太大,正如下边链接地址里博主在10版本下的方法,在6.0版本长也是这样 http://blog.sina.com ...

  10. Webbrowser 在web项目中的使用

    string htmlstr = string.Empty; [STAThread] public string GetHtmlByWeb(string url) { try { RunWithSin ...