linux互斥鎖簡介(核心態)
一、什麼是互斥鎖
1、概念
互斥鎖(Mutex)是在原子操作API的基礎上實現的訊號量行為。互斥鎖不能進行遞迴鎖定或解鎖,能用於互動上下文但是不能用於中斷上下文,同一時間只能有一個任務持有互斥鎖,而且只有這個任務可以對互斥鎖進行解鎖。當無法獲取鎖時,執行緒進入睡眠等待狀態。
互斥鎖是訊號量的特例。訊號量的初始值表示有多少個任務可以同時訪問共享資源,如果初始值為1,表示只有1個任務可以訪問,訊號量變成互斥鎖(Mutex)。但是互斥鎖和訊號量又有所區別,互斥鎖的加鎖和解鎖必須在同一執行緒裡對應使用,所以互斥鎖只能用於執行緒的互斥;訊號量可以由一個執行緒釋放,另一個執行緒得到,所以訊號量可以用於執行緒的同步。
2、資料結構
結構體成員說明:
1、atomic_t count;
指示互斥鎖的狀態:1 沒有上鎖,可以獲得;0 被鎖定,不能獲得。初始化為沒有上鎖。
2、spinlock_t wait_lock;
等待獲取互斥鎖中使用的自旋鎖。在獲取互斥鎖的過程中,操作會在自旋鎖的保護中進行。初始化為為鎖定。
3、struct list_head wait_list;
等待互斥鎖的程序佇列。
二、如何使用互斥鎖
1、初始化
mutex_init(&mutex); //動態初始化互斥鎖
DEFINE_MUTEX(mutexname); //靜態定義和初始化互斥鎖
2、上鎖
void mutex_lock(struct mutex *lock);
無法獲得鎖時,睡眠等待,不會被訊號中斷。
int mutex_trylock(struct mutex *lock);
此函式是 mutex_lock()的非阻塞版本,成功返回1,失敗返回0。
int mutex_lock_interruptible(struct mutex *lock);
和mutex_lock()一樣,也是獲取互斥鎖。在獲得了互斥鎖或進入睡眠直到獲得互斥鎖之後會返回0。如果在等待獲取鎖的時候進入睡眠狀態收到一個訊號(被訊號打斷睡眠),則返回_EINIR。
3、解鎖
void mutex_unlock(struct mutex *lock);
三、什麼時候使用互斥鎖
1、互斥鎖和訊號量比較
a、互斥鎖功能上基本與二元訊號量一樣,但是互斥鎖佔用空間比訊號量小,執行效率比訊號量高。所以,如果要用於執行緒間的互斥,優先選擇互斥鎖。
2、互斥鎖和自旋鎖比較
a、互斥鎖在無法得到資源時,核心執行緒會進入睡眠阻塞狀態,而自旋鎖處於忙等待狀態。因此,如果資源被佔用的時間較長,使用互斥鎖較好,因為可讓CPU排程去做其它程序的工作。
b、如果被保護資源需要睡眠的話,那麼只能使用互斥鎖或者訊號量,不能使用自旋鎖。而互斥鎖的效率又比訊號量高,所以這時候最佳選擇是互斥鎖。
c、中斷裡面不能使用互斥鎖,因為互斥鎖在獲取不到鎖的情況下會進入睡眠,而中斷是不能睡眠的。