五、自旋锁(spinlock)

2024-06-15 06:58
文章标签 自旋 spinlock

本文主要是介绍五、自旋锁(spinlock),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

  由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。

  信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用(_trylock的变种能够在中断上下文使用),而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。

  如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共巷资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。

  自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP的情况下才真正需要,在单 CPU 且不可抢占的内核下,自旋锁的所有操作都是空操作。

  跟互斥锁一样,一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。

  无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。

  自旋锁的API有:

spin_lock_init(x)

  该宏用于初始化自旋锁x。自旋锁在真正使用前必须先初始化。该宏用于动态初始化。

DEFINE_SPINLOCK(x)

  该宏声明一个自旋锁x并初始化它。该宏在2.6.11中第一次被定义,在先前的内核中并没有该宏。

SPIN_LOCK_UNLOCKED

  该宏用于静态初始化一个自旋锁。

DEFINE_SPINLOCK(x)等同于spinlock_t x = SPIN_LOCK_UNLOCKED
spin_is_locked(x)

  该宏用于判断自旋锁x是否已经被某执行单元保持(即被锁),如果是,返回真,否则返回假。

spin_unlock_wait(x)

  该宏用于等待自旋锁x变得没有被任何执行单元保持,如果没有任何执行单元保持该自旋锁,该宏立即返回,否则将循环在那里,直到该自旋锁被保持者释放。

spin_trylock(lock)

  该宏尽力获得自旋锁lock,如果能立即获得锁,它获得锁并返回真,否则不能立即获得锁,立即返回假。它不会自旋等待lock被释放。

spin_lock(lock)

  该宏用于获得自旋锁lock,如果能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋锁的保持者释放,这时,它获得锁并返回。总之,只有它获得锁才返回。

spin_lock_irqsave(lock, flags)

  该宏获得自旋锁的同时把标志寄存器的值保存到变量flags中并失效本地中断。

spin_lock_irq(lock)

  该宏类似于spin_lock_irqsave,只是该宏不保存标志寄存器的值。

spin_lock_bh(lock)

  该宏在得到自旋锁的同时失效本地软中断。

spin_unlock(lock)

  该宏释放自旋锁lock,它与spin_trylock或spin_lock配对使用。如果spin_trylock返回假,表明没有获得自旋锁,因此不必使用spin_unlock释放。

spin_unlock_irqrestore(lock, flags)

  该宏释放自旋锁lock的同时,也恢复标志寄存器的值为变量flags保存的值。它与spin_lock_irqsave配对使用。

spin_unlock_irq(lock)

  该宏释放自旋锁lock的同时,也使能本地中断。它与spin_lock_irq配对应用。

spin_unlock_bh(lock)

  该宏释放自旋锁lock的同时,也使能本地的软中断。它与spin_lock_bh配对使用。

spin_trylock_irqsave(lock, flags)

这篇关于五、自旋锁(spinlock)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062744

相关文章

Java并发之AQS与自旋锁(利用CAS实现)

一、概述   谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!   类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。   以下是本文的目录大

高效编程之互斥锁和自旋锁的一些知识

转自:http://www.cnblogs.com/hdflzh/p/3716156.html 两种锁的加锁原理 互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。 自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。 两种锁的区别 互斥锁的起始原始开销要高于自旋锁,但是基

多线程篇(基本认识 - 公平锁 非公平锁、独占锁 共享锁、可重入锁、自旋锁)(持续更新迭代)

目录 锁一:公平锁与非公平锁 前言 一、Lock 锁接口 二、公平锁 1. 简介 三、非公平锁 1. 简介 四、JUC 1. ReentranLock 公平锁 非公平锁 锁二:独占锁 & 共享锁 前言 一、简介 二、代码示例 1. 未加锁状态 2. 加锁状态 锁三:可重入锁 前言 一、简介 二、代码示例 锁四:自旋锁 一、前言 二、问题思考 三、思

nginx学习之自旋锁nginx_spinlock

nginx中自旋锁简介: 基于原子操作,Nginx实现了一个自旋锁。自旋锁是一种非睡眠锁,也就是说,某进程如果试图获得自旋锁,当发现锁已经被其他进程获得时,那么不会使得当前进程进入睡眠状态,而是始终保持进程在可执行状态,每当内核调度到这个进程执行时就持续检查是否可以获取到锁。在拿不到锁时,这个进程的代码将会一直在自旋锁代码处执行(下面的源码会分析到),知道其他进程释放了锁且当前进程获取

【讯为Linux驱动开发】6.自旋锁spinlock

【自旋锁】 线程A获取自旋锁后,B假如想获取自旋锁则只能原地等待,仍占用CPU,不会休眠,直到获取自旋锁为止。 【函数】 DEFINE SÃINLOCK(spinlock t lock)   定义并初始化一个变量int spin lock init(spinlock t*lock)   初始化自旋锁void spin lock(spinlock t *lock)    获取自旋锁。也叫做加

【必会面试题】自旋中的ABA问题

目录 ABA问题描述ABA问题的影响解决ABA问题的方案 \qquad 自旋锁(spinlock)是一种用于实现互斥同步的锁机制,其基本思想是让线程在等待获取锁的过程中不断地检查锁是否可用,而不是进入睡眠状态。自旋锁适用于锁被持有的时间较短,且线程切换开销较大的场景。 ABA 问题是一个经典的并发问题,它发生在使用原子操作(如 CAS,Compare-And-Swap)实

自旋锁代替互斥锁的实践

转自:http://ifeve.com/practice-of-using-spinlock-instead-of-mutex/ 自旋锁和互斥锁是多线程程序中的重要概念。 它们被用来锁住一些共享资源, 以防止并发访问这些共享数据时可能导致的数据不一致问题。 但是它们的不同之处在哪里? 我们应该在什么时候用自旋锁代替互斥锁? 理论分析 从理论上说, 如果一个线程尝试加锁一个互斥锁的时候没有成功

JOS中 spinlock 的实现

JOS中  "spinlock" 的实现 In software engineering, a spinlock is a lock which causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking if the lock is availa

spinlock_t

头文件: #include <linux/spinlock.h> 定义: typedef struct spinlock {union {struct raw_spinlock rlock;#ifdef CONFIG_DEBUG_LOCK_ALLOC# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))struct

Linux内核源码阅读之自旋锁的作用及其实现

作用: 内核中的自旋锁的作用是保护一段临界区域的操作是独占的,不能因为多个CPU或者多个进程同时访问破坏数据结构。在单核系统和多核系统中自旋锁的实现有所不同。 多核系统: 对于多核系统,主要考虑一个cpu进入临界代码区域之后,其它cpu不能再次进入这个临界代码区域。 单核系统: 对于单核系统,主要的情景是一个进程进入了临界区域后,不能被其它进程抢占,如果被其他进程抢占,会导致进程抢占的c