linux 自旋锁spin_lock

1 概述

spin_lock 主要用于内核开发,用于在内核模块或内核代码中对共享资源进行互斥访问。它通常用于非抢占式内核环境,因为在抢占式内核中,内核线程可以在任何时间点被中断,这可能导致自旋锁在某些情况下陷入死锁。

1.1 spin_lock特点

  • spin_lock 是一种忙等待锁,它会在获取锁之前一直自旋等待。这意味着线程不会被挂起,而是会持续占用 CPU 资源,直到锁可用。
  • 自旋锁适用于临界区代码非常短暂且锁争用较少的情况,因为它不会在等待期间让出 CPU,可能会浪费大量的 CPU 时间。
  • 原子性:spin_lock 操作是原子的,它使用底层处理器原语(例如 x86 架构上的 xchg 指令或者 ARM 架构上的原子比较和交换指令)来确保锁的原子性。

1.2 spin_lock_irq

spin_lock_irq 会禁用本地中断(IRQs),这意味着中断服务程序(ISRs)无法在 spin_lock_irq 保护的临界区内执行,从而避免了竞争条件。

1.3 中断服务程序与普通线程同步的方式

  • 使用信号量:可以使用信号量作为中断服务程序和普通线程之间的同步机制。中断服务程序可以在访问共享资源之前获取信号量,而普通线程则在完成对共享资源的访问后释放信号量。
  • 使用自旋锁:自旋锁是一种用于互斥访问的锁定机制,可以在中断服务程序和普通线程之间使用。中断服务程序和线程都可以尝试获取自旋锁,但如果自旋锁已被持有,它们会自旋等待直到锁可用。

2 内核中使用实例

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

MODULE_LICENSE("GPL");

// 声明并初始化一个自旋锁
static DEFINE_SPINLOCK(my_spinlock);

// 共享资源
static int shared_data = 0;

static int my_init(void) {
    int i;

    printk(KERN_INFO "Initializing my module...\n");

    // 模拟多个线程同时访问共享资源
    for (i = 0; i < 5; i++) {
        if (fork() == 0) {
            // 子进程获取自旋锁
            spin_lock(&my_spinlock);

            // 访问共享资源
            shared_data++;
            printk(KERN_INFO "Child process: shared_data = %d\n", shared_data);

            // 释放自旋锁
            spin_unlock(&my_spinlock);

            // 退出子进程
            _exit(0);
        }
    }

    // 等待所有子进程退出
    for (i = 0; i < 5; i++) {
        wait(NULL);
    }

    printk(KERN_INFO "All child processes have exited. Final shared_data = %d\n", shared_data);

    return 0;
}

static void my_exit(void) {
    printk(KERN_INFO "Exiting my module...\n");
}

module_init(my_init);
module_exit(my_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天选码农搬砖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值