1. 程式人生 > >Linux的自旋鎖spin原始碼解析

Linux的自旋鎖spin原始碼解析

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中, 自旋鎖當條件不滿足時,會一直不斷地迴圈條件是否被滿足。如果滿足,就解鎖,繼續執行下面的程式碼。這種忙等待機制是否對系統的效能有所影響呢?答案是肯定的。核心這樣設計自旋鎖確定對系統的效能,有所影響,所以在實際程式設計中,程式設計師應該注意自旋鎖不應該長時間地持有,它 "是一種適合短時間鎖定的輕量級的加鎖機制。

自旋鎖不能遞迴使用(即已經拿到鎖的執行緒,不應該再等待拿到的那個鎖)

這是因為, 自旋鎖被設計成在不同執行緒或者函式之間同步。如果一個執行緒在已經持有自旋鎖時,其處於忙等待狀態,則已經沒有機會釋放自,己持有的鎖了。如果這時再呼叫自身,則自旋鎖永遠沒有執行的機會了。所以類似下面的遞迴形式是不能使用自旋鎖的。