Linux内核源码之自旋锁的实现

本文详细介绍了Linux内核中的自旋锁机制,包括单处理器和多处理器环境下的实现。自旋锁用于保护共享资源,确保任意时刻只有一个进程访问。在单处理器系统中,自旋锁主要通过关闭内核抢占来实现;而在多处理器系统中,通过总线锁确保原子性。文章还提到了更安全的spin_lock_irqsave()和spin_unlock_irqrestore()函数,以及自旋锁使用时应避免进入睡眠状态的原则。
摘要由CSDN通过智能技术生成

1 Linux内核同步
Linux内核中有许多共享资源,这些共享资源是内核中进程都有机会访问到的。内核对其中一些共享资源的访问是独占的,因此需要提供机制对共享资源进行保护,确保任意时刻只有一个进程在访问共享资源。自旋锁就是一种共享资源保护机制,确保同一时刻只有一个进程能访问到共享资源。

2 普通自旋锁
内核中提供的普通自旋锁API为spin_lock()何spin_unlock(),使用的方法为:

        spin_lock();
        ...临界区...
        spin_unlock();

内核保证spin_lock()和spin_unlock()之间的临界区代码在任意时刻只会由一个CPU进行访问,并且当前CPU访问期间不会发生进程切换,当前进程也不会进入睡眠,这个在后面还会进一步分析。

3 单处理器(UP)普通自旋锁
之前讲过,自旋锁的功能有两点,一是临界区代码任意时刻由一个CPU进行访问,二是当前CPU访问期间不会发生进程切换。对于单处理器来说第一个问题就不存在了,因为只有一个CPU,不存在多处理器访问的问题。因此单处理器自旋锁只要保证CPU对临界区代码访问期间不发生进程切换就行了。知道了这一点后让我们来看看单处理器普通自旋锁使用的数据结构和API的实现代码。以下代码和数据结构使用的内核版本是Linux-2.6.24,特此注明。

3.1 数据结构
普通自旋锁的数据类型为spinlock_t:

        typedef struct {
                raw_spinlock_t raw_lock;
        #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
                unsigned int break_lock;
        #endif
        #ifdef CONFIG_DEBUG_SPINLOCK
                unsigned int magic, owner_cpu;
                void *owner;
        #endif
        #ifdef CONFIG_DEBUG_LOCK_ALLOC
                struct lockdep_map dep_map;
        #endif
        } spinlock_t;

可以看出,去掉了编译配置选项之后其实spinlock_t里只剩下了类型为raw_spinlock_t的数据结构raw_lock:


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值