Linux的自旋锁spin源码解析

版权声明:转载请声明 https://blog.csdn.net/qq_40732350/article/details/83049367

1. 概述——————————————————————

在Linux中提供了一些锁机制来避免竞争条件,最简单的一种就是自旋锁。引入锁的机制,是因为单独的原子操作不能满足复杂的内核设计需要。

例如,当一个临界区域要在,多个函数之间来回运行时,原子操作就显得无能为力了。

Linux中一般可以认为有两种锁,一种是自旋锁,另一种是信号量。这两种锁是为了解决内核中遇到的不同问题开发的。

2.原理———————————————————————

结构体:

typedef struct spinlock {
	union {
		struct raw_spinlock rlock;
                //中间的DEBUG删除了
	       };
} spinlock_t;

上锁函数:

//          一般的上锁
static inline void spin_lock(spinlock_t *lock)
{
	raw_spin_lock(&lock->rlock);
}
//           通常用在进程中,用来禁止抢断和禁止软中断
static inline void spin_lock_bh(spinlock_t *lock)
{
	raw_spin_lock_bh(&lock->rlock);
}
//          判断有没有上锁
static inline int spin_trylock(spinlock_t *lock)
{
	return raw_spin_trylock(&lock->rlock);
}
//           既禁止本地中断,又禁止内核抢占
static inline void spin_lock_irq(spinlock_t *lock)
{
	raw_spin_lock_irq(&lock->rlock);
}

解锁函数:

static inline void spin_unlock(spinlock_t *lock)
{
	raw_spin_unlock(&lock->rlock);
}

static inline void spin_unlock_bh(spinlock_t *lock)
{
	raw_spin_unlock_bh(&lock->rlock);
}

static inline void spin_unlock_irq(spinlock_t *lock)
{
	raw_spin_unlock_irq(&lock->rlock);
}

static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
{
	raw_spin_unlock_irqrestore(&lock->rlock, flags);
}

3.使用——————————————————————————

spinlock t lock;
spin lock init (&lock);
spin lock (&lock);
//临界资源
spin unlock (&lock);

注意:

自旋锁是一种忙等待

Linux中, 自旋锁当条件不满足时,会一直不断地循环条件是否被满足。如果满足,就解锁,继续运行下面的代码。这种忙等待机制是否对系统的性能有所影响呢?答案是肯定的。内核这样设计自旋锁确定对系统的性能,有所影响,所以在实际编程中,程序员应该注意自旋锁不应该长时间地持有,它 "是一种适合短时间锁定的轻量级的加锁机制。

自旋锁不能递归使用(即已经拿到锁的线程,不应该再等待拿到的那个锁)

这是因为, 自旋锁被设计成在不同线程或者函数之间同步。如果一个线程在已经持有自旋锁时,其处于忙等待状态,则已经没有机会释放自,己持有的锁了。如果这时再调用自身,则自旋锁永远没有执行的机会了。所以类似下面的递归形式是不能使用自旋锁的。

猜你喜欢

转载自blog.csdn.net/qq_40732350/article/details/83049367