目录
 
1、自旋锁作用与基本使用方法?
与其他锁一样,自旋锁也用于保护临界区,但是自旋锁主要是用于在SMP上保护临界区。在SMP上,自旋锁最多只能被一个可执行线程持有,如果一个线程尝试获得一个被争用的自旋锁,该线程将一直旋转(while循环)直到锁可用;如果锁未被争用,请求锁的执行线程将立刻争用它,并继续执行。
 
LINUX下自旋锁的基本使用方法:
声明锁:
spinlock_t lock;
 
初始化:
lock = SPIN_LOCK_UNLOCKED;
     或者
spin_lock_init(&lock);
 
加锁有4个接口,3个会阻塞,1个不阻塞
spin_lock(&lock);//获取自旋锁
spin_lock_irq(&lock);//关中断,获取自旋锁,不建议使用
spin_lock_irqsave(&lock, flags);//关中断,保存中断状态,获取自旋锁
spin_trylock(&lock);//与spin_lock一样,但是获取不到的时候不阻塞,返回非0
 
对应的解锁接口有3个
spin_unlock(&lock);//spin_lock和spin_trylock都用该接口解锁
spin_unlock_irq(&lock);//不建议使用
spin_unlock_irqrestore(&lock, flags);
 
另外还提供了一个获取锁状态的接口:
spin_is_locked(&lock);//如果指定的锁被获取,返回非0,否则,返回0
 
2、在SMP和UP上的不同表现?
对于SMP,自旋锁将在禁止抢占后,while循环自旋直到锁可用;
对于UP,自旋锁的行为有点不一样,具体表现为:
  • 内核不支持抢占,则spin_lock是个空函数,spin_unlock也是空函数;
  • 内核支持抢占,则spin_lock关抢占,spin_unlock开抢占。
要分析SMP和UP的区别,还得先理解UP下内核支持抢占与否的区分。
在不支持抢占的时候,内核调度时机为:
  • 内核代码一直要执行到完成(返回用户空间);
  • 阻塞或主动调用schedule();
支持内核抢占的内核,则在以下情况会发生抢占:
  • 从中断处理程序回到内核空间且内核具有抢占性时;
  • 当内核代码再一次具有可抢占性时;(如时钟中断,发现进程时间片已经用完,则发生进程抢占)
  • 内核显式调用schedule();
  • 内核中的任务阻塞(同样导致schedule());

从以上区别可以看出,若是内核不支持抢占,只要临界区的代码不阻塞,就能保证原子性,所以spin_lock/spin_unlock是空函数。

而对于支持抢占的内核, spin_lock/spin_unlock自然只需要关闭/恢复抢占功能即可。
 
 
3、自旋锁与上下文
由于自旋锁不睡眠,既可以用于进程上下文,也可用于非进程上下文,这是它与信号量相比的一个优势。
正常来讲,如果自旋锁都是在进程上下文中使用,则建议使用spin_lock/spin_unlock。
若在中断处理例程中也要使用自旋锁,则所有争用同一个锁的地方应使用spin_lock_irqsave/spin_unlock_irqrestore。
若没有在中断而在下半部使用自旋锁,则所有急用同一个锁的地方可以使用spin_lock_bh/spin_unlock_bh,这对函数平时用得比较少。
注:自旋锁用在中断例程中,若是进程上下文中的内核代码使用spin_lock,则在临界区,可能发生中断 ,要么原子性被破坏(UP),要么造成死锁(SMP).
 
4、使用spin_lock()后为什么不能睡眠?
在UP下,正如前面所说,原子性得不到保证。
而在SMP下,则可能发生死锁:
假设有3个进程A,B,C,2个CPU称CPU0,CPU1.
CPU0上A进程获取自旋锁进入睡眠,调度了B进程,B进程将自旋; 
CPU1上调度了C进程也将自旋。
B等着A释放锁,A等着B释放CPU,自旋后的CPU不能发生调度,CPU0和CPU1将一直自旋下去,形成了死锁。
 
 
5、强调:锁什么?
使用锁的时候一定要对症下药,明确保护的是数据而不是代码,这是使用锁的正确思考方式。经常看别人代码的人应该会有所体会,针对代码加锁常常使代码难以理解,特别是复杂的程序,往往加锁没做好,引起竞争条件。
不防在使用锁的时候先思考一下自己要保护什么,然后给对应的锁取跟数据相关的名称。比如"int foo;spinlock_t foo_lock;"表示foo由foo_lock加锁;
 
6、参考
《Linux内核设计与实现》

LINUX内核笔记:自旋锁的更多相关文章

  1. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析

    转自:http://blog.csdn.net/wh_19910525/article/details/11536279 自旋锁的初衷:在短期间内进行轻量级的锁定.一个被争用的自旋锁使得请求它的线程在 ...

  2. [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析【转】

    转自:https://www.cnblogs.com/x_wukong/p/8573602.html 转自;https://www.cnblogs.com/aaronLinux/p/5890924.h ...

  3. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  4. 【转载】linux内核笔记之进程地址空间

    原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...

  5. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  6. linux内核笔记-内核同步

    linux内核就相当于不断对请求进行响应的服务器,这些请求可能来自CPU,可能来自发出中断的外部设备.我们将内核看作两种请求的侍者. (1)老板提出请求,侍者如果空闲,为老板服务.(系统调用或异常) ...

  7. [转]透过 Linux 内核看无锁编程

    非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...

  8. Linux内核笔记:epoll实现原理(一)

    一.说明 针对的内核版本为4.4.10. 本文只是我自己看源码的简单笔记,如果想了解epoll的实现,强烈推荐下面的文章: The Implementation of epoll(1) The Imp ...

  9. Linux内核笔记--深入理解文件描述符

    内核版本:linux-2.6.11 文件描述符(file descriptor)在Linux编程里随处可见,设备读写.网络通信.进程通信,fd可谓是关键中的关键. 深入理解可以增加我们使用它的信心. ...

随机推荐

  1. ThinkCMF变量输出+使用函数

    ThinkCMF变量输出+使用函数的方式同ThinkPHP. ThinkPHP变量输出: 在模板中输出变量的方法很简单,例如,在控制器中我们给模板变量赋值: $name = 'ThinkPHP'; $ ...

  2. Spark集群 + Akka + Kafka + Scala 开发(3) : 开发一个Akka + Spark的应用

    前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境中,我们已经部署好了一个Spark的开发环境. 在Spark集群 + Akka + Kafka + S ...

  3. SDL教程第一和第二个视频的笔记

    观看正月点灯笼的SDL教程,地址http://www.tudou.com/listplay/9eG9tkk91oQ.html #include <stdio.h> #include < ...

  4. Java的自动递增和递减

    和C 类似,Java 提供了丰富的快捷运算方式.这些快捷运算可使代码更清爽,更易录入,也更易读者辨读.两种很不错的快捷运算方式是递增和递减运算符(常称作"自动递增"和"自 ...

  5. lodash链式使用

    chain var _ = require('lodash'); var user1 = { name: 'zhangsan', height: 180, weight: 120 }; var use ...

  6. GJM : Unity3D - NetWork - Hight Level API ( HLAPI) [转载]

    介绍在本系列教程中,我们将使用的网络高级API(HLAPI)来构建一个小型的多人网络案例.即使我们的例子很简单,但也会涵盖以下关键概念,这应该可以帮助大家使用HLAPI构建大型游戏项目. 在第一部分, ...

  7. java.io.StreamCorruptedException: invalid type code: AC错误的解决方法

    问题描述: 在向一个文件写入可序列化对象时,每次只想向文件的末尾添加一个可序列化的对象,于是使用了FileOutputStream(文件名,true)间接的构建了ObjectOutputStream流 ...

  8. Guacamole之实现和架构(一)

    摘要 在网上看到一篇Guacamole官方手册的翻译,但是找不到后续,于是想自己也翻译几篇,有时间的话,会尽量多翻译一些.第一篇就直接转载过来了. Guacamole的介绍以及架构 Guacamole ...

  9. Linux文件查看/编辑方法介绍

    转载:https://www.centos.bz/2011/10/linux-file-view-edit/ cat 命令介绍 cat 命令的原含义为连接(concatenate), 用于连接多个文件 ...

  10. win server 2008 r2 sharepoint 域环境安装经历

    环境: 物理机:win7(x64,计算机名字:wyman-pc,ip:192.168.10.102)  / sql server 2008 r2(x64) /VM10 虚拟机:win svr 2008 ...