linux内核锁机制学习
在現(xiàn)代操作系統(tǒng)里,同一時間可能有多個內(nèi)核執(zhí)行流在執(zhí)行,因此內(nèi)核其實(shí)象多進(jìn)程多線程編程一樣也需要一些同步機(jī)制來同步各執(zhí)行單元對共享數(shù)據(jù)的訪問。尤其是在多處理器系統(tǒng)上,更需要一些同步機(jī)制來同步不同處理器上的執(zhí)行單元對共享的數(shù)據(jù)的訪問。
在主流的Linux內(nèi)核中包含了幾乎所有現(xiàn)代的操作系統(tǒng)具有的同步機(jī)制,這些同步機(jī)制包括:原子操作、信號量(semaphore)、讀寫信號量(rw_semaphore)、spinlock、BKL(Big Kernel Lock)、rwlock、brlock(只包含在2.4內(nèi)核中)、RCU(只包含在2.6內(nèi)核中)和seqlock(只包含在2.6內(nèi)核中)。
?
原子操作
原子操作就是指某一個操作在執(zhí)行過程中不可以被打斷,要么全部執(zhí)行,要不就一點(diǎn)也不執(zhí)行。
? ? 原子整數(shù)操作只對atomic_t類型的數(shù)據(jù)進(jìn)行操作,不能對C語言的int進(jìn)行操作,
? 原子操作API包括:
原子讀,返回原子類型的變量v的值;
設(shè)置原子類型的變量v的值為i;
? ? ? ?給原子類型的變量v增加值i;
? ? ? ?從原子類型的變量v中減去i;
? ? ? ?從原子類型的變量v中減去i,并判斷結(jié)果是否為0;
? ? ? ?對原子類型變量v原子地增加1;
? ? ? ?對原子類型的變量v原子地減1;
? ? ? ?對原子類型的變量v原子地減1,并判斷結(jié)果是否為0;
? ? ? ?對原子類型的變量v原子地增加1,并判斷結(jié)果是否為0;
? ? ? ?對原子類型的變量v原子地增加I,并判斷結(jié)果是否為負(fù)數(shù);
? ? ? ?對原子類型的變量v原子地增加i,并且返回指向v的指針;
? ? ? ?從原子類型的變量v中減去i,并且返回指向v的指針;
? ? ? ?對原子類型的變量v原子地增加1并且返回指向v的指針;
? ? ? ?對原子類型的變量v原子地減1并且返回指向v的指針;
自旋鎖
Linux自旋鎖保證了任意時刻只能有一個執(zhí)行線程進(jìn)入臨界區(qū),其他試圖進(jìn)入臨界區(qū)的線程將一直進(jìn)行嘗試(即自旋),直到獲得該鎖。
自旋鎖的本質(zhì)是對內(nèi)存區(qū)域的一個整數(shù)的操作,任何線程進(jìn)入臨界區(qū)之前都必須檢查該整數(shù),可用則進(jìn)入,都則一直忙循環(huán)等待。
? ? Linux自旋鎖主要應(yīng)用與多核處理器中,單CPU中不會進(jìn)行自旋鎖操作。
? ? 何時使用自旋鎖?不允許睡眠的上下文且臨界區(qū)操作較短時使用自旋鎖。
BKL(Big Kernel Lock)
BKL即全局內(nèi)核鎖,也稱大內(nèi)核鎖,它是一個全局自旋鎖。大內(nèi)核鎖也是用來保護(hù)臨界區(qū)資源的,避免出現(xiàn)多個處理器上的進(jìn)程同時訪問同一區(qū)域,整個內(nèi)核中只有一個大內(nèi)核鎖。
BKL是一個名為kernel_flag的自旋鎖,持有該鎖的進(jìn)程仍可以睡眠,當(dāng)睡眠時持有的鎖將被自動釋放,該進(jìn)程被喚醒時重新持有該鎖。Linux允許一個進(jìn)程可以遞歸的持有BKL,BKL是一個遞歸鎖。
? ? 自旋鎖加鎖的對象一般是一個全局變量,大內(nèi)核鎖加鎖的對象是一段代碼,里面可能包含多個全局變量。
mutex(互斥鎖)
定義在:/linux/include/linux/mutex.h
struct mutex {
? ? ? ? atomic_t count;
? ? ? ? spinlock_t wait_lock;
? ? ? ? struct list_head wait_list;
? ? ? ? #ifdef CONFIG_DEBUG_MUTEXES
? ? ? ? struct thread_info *owner;
? ? ? ? const char *name;
? ? ? ? void *magic;
? ? ? ? #endif
? ? ? ? #ifdef CONFIG_DEBUG_LOCK_ALLOC
? ? ? ? struct lockdep_map dep_map;
? ? ? ? #endif
? ? };
? ? 互斥鎖主要用于實(shí)現(xiàn)內(nèi)核中的互斥訪問功能。內(nèi)核互斥鎖是在原子API之上實(shí)現(xiàn)的,但這對于內(nèi)核用戶是不可見的。
? ? 互斥鎖不能進(jìn)行遞歸鎖定或解鎖。一個互斥鎖對象必須通過其API初始化,而不能使用memset或復(fù)制初始化。一個任務(wù)在持有互斥鎖的時候是不能結(jié)束的。
? ? atomic_t count:指示互斥鎖的狀態(tài):1沒有上鎖,可以獲得;0被鎖定,不能獲得;負(fù)數(shù)被鎖定,且可能在該鎖上有等待進(jìn)程初始化為沒有上鎖。
? ? spinlock_t wait_lock:等待獲取互斥鎖中使用的自旋鎖;在獲取互斥鎖的過程中,操作會在自旋鎖的保護(hù)中進(jìn)行;初始化為為鎖定;
? ? struct list_head wait_list:等待互斥鎖的進(jìn)程隊(duì)列。
順序鎖
順序鎖為寫者賦予更高的優(yōu)先級,寫者永遠(yuǎn)不會等待讀者。
順序鎖的數(shù)據(jù)結(jié)構(gòu)中除了有spinlock外,還有一個順序號。
總結(jié)
以上是生活随笔為你收集整理的linux内核锁机制学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GIS可视性分析概述
- 下一篇: 图解在emu8086中学习汇编语言数字比