首页 > 其他分享 >自旋锁spinlock

自旋锁spinlock

时间:2024-03-25 20:47:26浏览次数:21  
标签:lock 线程 自旋 my spin spinlock

参考资料: 《正点原子Linux驱动教程》 《宋宝华 Linux设备驱动开发详解》   原子操作只能对整型变量或者bit位进行保护,但是实际使用中,不可能只有整型变量或者bit位等临界区   自旋锁spinlock也是一种典型的对临界资源进行互斥访问的手段,其名称来源自它的工作方式。 当一个线程要访问某个共享资源的时候首先要先获取相应的锁,锁只能被一个线程持有,只要此线程不释放持有的锁,那么其他的线程就不能获取此锁。对于自旋锁而言,如果自旋锁正在被线程 A 持有,线程 B 想要获取自旋锁,那么线程 B 就会处于忙循环-旋转-等待状态   自旋锁简化定义:

typedef struct {
    arch_spinlock_t raw_lock;
} spinlock_t;
 

自旋锁的相关操作:

spinlock_t lock;            // 定义自旋锁
spin_lock_init(lock)        // 初始化自旋锁
spin_lock(lock)             // 获取自旋锁
spin_unlock(lock)           // 释放自旋锁

 

自旋锁使用demo:

DEFINE_SPINLOCK(lock) /* 定义并初始化一个锁 */

/* 线程 A */
void functionA (){
    unsigned long flags; /* 中断状态 */
    spin_lock_irqsave(&lock, flags) /* 获取锁 */
    /* 临界区 */
    spin_unlock_irqrestore(&lock, flags) /* 释放锁 */
}

/* 中断服务函数 */
void irq() {
    spin_lock(&lock) /* 获取锁 */
    /* 临界区 */
    spin_unlock(&lock) /* 释放锁 */
}
自旋锁主要针对SMP或单CPU但内核可抢占的情况,对于单CPU和内核不支持抢占的系统,自旋锁退化为空操作。自旋锁持有期间内核抢占将被禁止。在多核SMP的情况下,任何一个核拿到了自旋锁,该核上的抢占调度也被暂时禁止了,但是没有禁止另外的核抢占调度 尽管用了自旋锁可以保证临界区不受别的CPU和本CPU内抢占进程的打扰,但是得到锁的代码路径在执行临界区的时候,还可能收到中断的影响,为了防止这种影响,就出现了自旋锁的衍生: 0 本地中断:自旋锁单个核心的中断   在SMP编程中,如果进程和中断都有可能访问同一片临界资源时,一般在进程上下文调用spin_lock_irqsave()和spin_lock_irqrestore(),在中断上下文调用spin_lock()和spin_unlock() 编写驱动程序时,需要注意下面的几个问题: 1、自旋锁实际上是忙等待,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。因此,只有在占用锁的时间极短的情况下,使用自旋锁才是合理的。当临界区很大或共享设备的时候,需要较长时间占用锁,这种情况使用自旋锁会降低系统性能 2、自旋锁可能导致系统死锁,引发这个问题最常见的情况是递归使用一个自旋锁,即如果一个已经拥有某个自旋锁的CPU想第二次获取到这个自旋锁,则该CPU将死锁 3、自旋锁锁定期间不能调度会引起进程调度的函数,如果进程获取自旋锁之后再阻塞,如使用copy_from_user()、copy_to_user()、kmalloc()和msleep()等函数,则会导致系统的崩溃  

spinlock测试demo:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/delay.h>

DEFINE_SPINLOCK(my_spinlock);
static int shared_data = 0;

static struct task_struct *my_thread1;
static struct task_struct *my_thread2;

int my_thread_func(void *data)
{
    int i;
    for (i = 0; i < 5; i++) {
        spin_lock(&my_spinlock);
        shared_data++;
        printk(KERN_INFO "Thread %s: Incrementing shared data - %d\n", (char *)data, shared_data);
        spin_unlock(&my_spinlock);
        msleep(1000); // 模拟一些工作
    }
    do_exit(0);
    return 0;
}

static int __init demo_init(void)
{
    printk(KERN_INFO "Demo: Initializing driver\n");

    // 创建两个内核线程
    my_thread1 = kthread_run(my_thread_func, "1", "my_thread1");
    my_thread2 = kthread_run(my_thread_func, "2", "my_thread2");

    return 0;
}

static void __exit demo_exit(void)
{
    if (my_thread1)
        kthread_stop(my_thread1);
    if (my_thread2)
        kthread_stop(my_thread2);

    printk(KERN_INFO "Demo: Exiting driver\n");
}

module_init(demo_init);
module_exit(demo_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lethe1203");
MODULE_DESCRIPTION("spinlock demo");

 

 

标签:lock,线程,自旋,my,spin,spinlock
From: https://www.cnblogs.com/lethe1203/p/18095274

相关文章

  • Linux第79步_使用自旋锁保护某个全局变量来实现“互斥访问”共享资源
    自旋锁使用注意事项:自旋锁保护的“临界区”要尽可能的短。因此,在open()函数中申请“spinlock_t自旋锁结构变量”,然后在release()函数中释放“spinlock_t自旋锁结构变量”,这种方法就行不通了。如果使用一个变量“dev_stats”来表示“共享资源的使用标志”,则“dev_stats>0”,......
  • synchronized 原理 (偏向锁、轻量级锁、锁膨胀、自旋)
    synchronized原理Synchronized是Java中用于实现线程同步的关键字,它可以用于方法或代码块。当一个方法或代码块被synchronized修饰时,它将在任意时刻只允许一个线程访问,保证了多线程环境下的数据安全性。synchronized可用于修饰对象或方法:方法上的synchronizedclassTest......
  • 全志R128 SDK HAL 模块开发指南之HW Spinlock
    模块介绍hwspinlock提供一种硬件同步机制,lock操作可以防止多处理器同时处理共享数据。保证数据的一致性。源码结构├──hal_hwspinlock.c├──hwspinlock.h├──Kconfig├──Makefile├──platform│├──hwspinlock-sun20iw2.h└──platform-hwspinlock......
  • linux之自旋锁(二千字长文)
    linux之自旋锁常见的各种锁悲观锁:在每次取数据时,总是担心数据会被其他线程修改,所以会在取数据前先加锁(读锁,写锁,行锁等),当其他线程想要访问数据时,被阻塞挂起。总是先行认为数据一定会被修改!所以要先加锁!保证没有人能够访问它!==我们学的同步互斥机制!其实都是属于悲观锁的范畴!==......
  • Linux内核在RISC-V架构下的spinlock实现
    riscv没有sev/wfe指令,当前无法在spinlock时省功耗,只能通过while循环不断检查条件。本文分析linux内核下对于spinlock的实现,具体到RISC-V体系结构。由于RISC-V体系结构下目前只是简单的实现了一个基于TAS的最基本的spinlock,本文的另一个附加任务就是分析Linux内核为各个平台下实......
  • 自旋锁
    自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上线文切换的消耗,缺点是循环会消耗CPU。publicfinalintgetAndAddInt(Objectvar1,longvar2,intvar4){intvar5;do{var5=this.getIntVolatile(var1,var2);}wh......
  • 自旋锁
    ⾃旋锁(spinlock):是指当⼀个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。⾃旋锁与互斥锁⽐较类似,它们都是为了解决对某项资源的互斥使⽤。⽆论是互斥锁,还是⾃旋锁,在任何时刻,最多只能有⼀个保持者......
  • 硬件自旋锁框架 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/locking/hwspinlock.html硬件自旋锁框架简介硬件自旋锁模块为异构处理器和不在单一共享操作系统下运行的处理器之间的同步和互斥提供硬件辅助。例如,OMAP4具有双核Cortex-A9、双核Cortex-M3和一个C64x+DSP,每个处理器运行不同的操作系......
  • CAS自旋锁到底是什么?为什么能实现线程安全?
    ......
  • 自旋锁探秘
    spinlock和mutexSpinlock是linux内核中常用的一种互斥锁机制,和mutex不同,当无法持锁进入临界区的时候,当前执行线索不会阻塞,而是不断的自旋等待该锁释放。正因为如此,自旋锁也是可以用在中断上下文的。也正是因为自旋,临界区的代码要求尽量的精简,否则在高竞争场景下会浪费宝贵的CPU......