访问共享资源的代码区域称作临界区。自旋锁(spin_lock)和互斥锁(mutex_lock)是保护内核临界区的两种基本机制。我们逐个分析。

自旋锁可以确保在同时只有一个线程进入临界区。其他想进入临界区的线程必须不停地原地打转,直到第1个线程释放自旋锁。注意:这里所说的线程不是内核线程,而是执行的线程。

理解自旋锁最简单的方法是把它作为一个变量看待,该变量把一个临界区或者标记为“我当前在运行,请稍等一会”或者标记为“我当前不在运行,可以被使用” 。如果 A 执行单元首先进入例程,它将持有自旋锁;当 B 执行单元试图进入同一个例程时,将获知自旋锁已被持有,需等到 A 执行单元释放后才能进入。

驱动工程师应谨慎使用自旋锁,而且在使用中还要特别注意如下几个问题。
1、自旋锁实际上是忙等锁,当锁不可用时,CPU 一直循环执行“测试并设置”该锁直到可用而取得该锁, CPU 在等待自旋锁时不做任何有用的工作, 仅仅是等待。 因此, 只有在占用锁的时间极短的情况下, 使用自旋锁才是合理的。当临界区很大或有共享设备的时候,需要较长时间占用锁,使用自旋锁会降低系统的性能。
2、自旋锁可能导致系统死锁。 引发这个问题最常见的情况是递归使用一个自旋锁,即如果一个已经拥有某个自旋锁的 CPU 想第二次获得这个自旋锁,则该 CPU 将死锁。此外,如果进程获得自旋锁之后再阻塞,也有可能导致死锁的发生。copy_from_user()、copy_to_user()和 kmalloc()等函数都有可能引起阻塞,因此在自旋锁的占用期间不能调用这些函数。

自旋锁的基本用法:

 //添加头文件#include <linux/spinlock.h> //定义和初始化自旋锁spinlockspinlock_t my_lock; //定义自旋锁spinlockspin_lock_init(&my_lock); //初始化自旋锁spinlockspin_lock(&my_lock); //获取指定的自旋锁spinlock,保护临界区... /*临界资源*/spin_unlock(&my_lock); //释放指定的锁spinlock

与自旋锁不同的是,互斥锁在进入一个被占用的临界区之前不会原地打转,而是使当前线程进入睡眠状态。如果要等待的时间较长,互斥锁比自旋锁更合适,因为自旋锁会消耗CPU资源。在使用互斥锁的场合,多于2次进程切换时间都可被认为是长时间,因此一个互斥锁会引起本线程睡眠,而当其被唤醒时,它需要被切换回来。

因此,在很多情况下,决定使用自旋锁还是互斥锁相对来说很容易:

(1) 如果临界区需要睡眠,只能使用互斥锁,因为在获得自旋锁后进行调度、抢占以及在等待队列上睡眠都是非法的;

(2) 由于互斥锁会在面临竞争的情况下将当前线程置于睡眠状态,因此,在中断处理函数中,只能使用自旋锁。

互斥锁使用的基本方法:

 //添加头文件#include <linux/mutex.h> //函数mutex_init()原型:void mutex_init(struct mutex *mutex);//定义和初始化互斥锁mutexstruct mutex my_mutex;    //定义互斥锁mutexmutex_init(&my_mutex);    //初始化互斥锁mutex mutex_lock(&my_mutex);    //获取互斥锁mutex ... /*临界资源*/mutex_unlock(&my_mutex); //释放互斥锁mutex

linux内核的自旋锁spin_lock和互斥锁mutex_lock相关推荐

  1. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  2. linux进程线程同步之 - POSIX线程互斥锁

    POSIX线程互斥锁 使用范围:线程同步 本文转自:http://blog.csdn.net/jiebaoabcabc/article/details/37914769 一.函数介绍 1.初始化互斥锁 ...

  3. python互斥锁原理_Linux 互斥锁的实现原理(pthread_mutex_t)

    引言 互斥锁大都会使用,但是要了解其原理就要花费一番功夫了.尽管我们说互斥锁是用来保护一个临界区,实际上保护的是临界区中被操纵的数据. 互斥锁还是分为三类:快速互斥锁/递归互斥锁/检测互斥锁 fute ...

  4. 互斥锁机制,互斥锁与读写锁区别

    Linux的4种锁机制: 互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象.当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒 读写锁:rwlock,分为读锁和写锁.处于读操作时 ...

  5. 同步方法中的锁对象_互斥锁与读写锁:如何使用锁完成Go程同步?

    图转自https://colobu.com/2018/12/18/dive-into-sync-mutex/ 这张图容易让人产生误解,容易让人误以为goroutine1获取的锁,只有goroutine ...

  6. android 线程互斥锁,多线程编程-互斥锁

    1.引言: 互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源.可以保证以下三点: 原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果 ...

  7. Linux内核同步方法——自旋锁(spin lock)

    自旋锁 Linux的的内核最常见的锁是自旋锁.自旋锁最多只能被一个可执行线程持有.如果一个执行线程试图获得一个被已经持有(争用)的自旋锁,那么该线程就会一直进行忙循环-旋转-等待锁重新可用要是锁未被争 ...

  8. linux内核自旋锁解释,LINUX内核笔记:自旋锁

    目录 1.自旋锁作用与基本使用方法? 与其他锁一样,自旋锁也用于保护临界区,但是自旋锁主要是用于在SMP上保护临界区.在SMP上,自旋锁最多只能被一个可执行线程持有,如果一个线程尝试获得一个被争用的自 ...

  9. linux内核的自旋锁

    前言 感谢宋老师. 自旋锁(Spin Lock)是一种典型的对临界资源进行互斥访问的手段,其名称来源于它的工作方式.为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置(T ...

  10. linux 内核互斥体,Linux 内核同步(六):互斥体(mutex)

    互斥体 互斥体是一种睡眠锁,他是一种简单的睡眠锁,其行为和 count 为 1 的信号量类似.(关于信号量参考:Linux 内核同步(四):信号量 semaphore). 互斥体简洁高效,但是相比信号 ...

最新文章

  1. EffectiveC++ Item11
  2. 专家也要小心,HTTPS网址的网站就一定安全吗?
  3. 每日一皮:QA一来,大家都要靠边站!
  4. 一个小程序看流的读取
  5. js原生操作select、radio 、checkbox
  6. leetcode 423. Reconstruct Original Digits from English | 423. 从英文中重建数字(Java)
  7. cefsharp.wpf离线安装包下载_在vscode里编写c++程序(解决gdb下载失败问题)
  8. 双拓扑排序 HDOJ 5098 Smart Software Installer
  9. yum配置(源配置-光驱,ftp服务器;基本用法)
  10. oracle时间类型
  11. SSH项目搭建-01-使用idea创建Maven工程
  12. pr cpu100%_【Premiere】视频剪辑必装插件,5个PR插件推荐
  13. 智能合约语言Solidity教程系列2 - 地址类型介绍
  14. Leetcode 1284 Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
  15. 论文发表费用如何收费
  16. Dubbo实战入门,良心详解之作
  17. vue中使用市区(地区)联动 复制三步完成
  18. 数据库学习——10-13-聚合函数+GROUP BY+HAVING学习
  19. 流体力学发展史(转)
  20. Mac 自动代理切换

热门文章

  1. Bugtags 实时跟踪插件 - BugtagsInsta
  2. ZK框架笔记3、窗体组件
  3. 获取当前时间getDate()注意点
  4. C# Parse和Convert的区别分析
  5. Python eval 函数
  6. theano 后端爆内存
  7. 【新Attention】最强的Attention函数诞生啦,带给你意想不到的巨大提升!
  8. 【CTR】ESMM:多任务联合学习
  9. 【福利】本人自学深度学习的300G的学习资料愿与大家分享!一起进步!
  10. 【珍藏版】长文详解python正则表达式