深入淺出Linux裝置驅動之併發控制

2021-05-24 12:34:19 字數 1811 閱讀 4610

在驅動程式中,當多個執行緒同時訪問相同的資源時(驅動程式中的全域性變數是一種典型的共享資源),可能會引發"競態",因此我們必須對共享資源進行併發控制。linux核心中解決併發控制的最常用方法是自旋鎖與訊號量(絕大多數時候作為互斥鎖使用)。

自旋鎖與訊號量"類似而不類",類似說的是它們功能上的相似性,"不類"指代它們在本質和實現機理上完全不一樣,不屬於一類。

自旋鎖不會引起呼叫者睡眠,如果自旋鎖已經被別的執行單元保持,呼叫者就一直迴圈檢視是否該自旋鎖的保持者已經釋放了鎖,"自旋"就是"在原地打轉"。而訊號量則引起呼叫者睡眠,它把程序從執行佇列上拖出去,除非獲得鎖。這就是它們的"不類"。

但是,無論是訊號量,還是自旋鎖,在任何時刻,最多只能有乙個保持者,即在任何時刻最多只能有乙個執行單元獲得鎖。這就是它們的"類似"。

鑑於自旋鎖與訊號量的上述特點,一般而言,自旋鎖適合於保持時間非常短的情況,它可以在任何上下文使用;訊號量適合於保持時間較長的情況,會只能在程序 上下文使用。如果被保護的共享資源只在程序上下文訪問,則可以以訊號量來保護該共享資源,如果對共享資源的訪問時間非常短,自旋鎖也是好的選擇。但是,如 果被保護的共享資源需要在中斷上下文訪問(包括底半部即中斷處理控制代碼和頂半部即軟中斷),就必須使用自旋鎖。

與訊號量相關的api主要有:

定義訊號量

struct semaphore sem;

初始化訊號量

void sema_init (struct semaphore *sem, int val);

該函式初始化訊號量,並設定訊號量sem的值為val

void init_mutex (struct semaphore *sem);

該函式用於初始化乙個互斥鎖,即它把訊號量sem的值設定為1,等同於sema_init (struct semaphore *sem, 1);

void init_mutex_locked (struct semaphore *sem);

該函式也用於初始化乙個互斥鎖,但它把訊號量sem的值設定為0,等同於sema_init (struct semaphore *sem, 0);

獲得訊號量

void down(struct semaphore * sem);

該函式用於獲得訊號量sem,它會導致睡眠,因此不能在中斷上下文使用;

int down_interruptible(struct semaphore * sem);

該函式功能與down類似,不同之處為,down不能被訊號打斷,但down_interruptible能被訊號打斷;

int down_trylock(struct semaphore * sem);

該函式嘗試獲得訊號量sem,如果能夠立刻獲得,它就獲得該訊號量並返回0,否則,返回非0值。它不會導致呼叫者睡眠,可以在中斷上下文使用。

釋放訊號量

void up(struct semaphore * sem);

spinlock_t spin;

初始化自旋鎖

spin_lock_init(lock)

該巨集用於動態初始化自旋鎖lock

獲得自旋鎖

spin_lock(lock)

該巨集用於獲得自旋鎖lock,如果能夠立即獲得鎖,它就馬上返回,否則,它將自旋在那裡,直到該自旋鎖的保持者釋放;

spin_trylock(lock)

該巨集嘗試獲得自旋鎖lock,如果能立即獲得鎖,它獲得鎖並返回真,否則立即返回假,實際上不再"在原地打轉";

釋放自旋鎖

spin_unlock(lock)

該巨集釋放自旋鎖lock,它與spin_trylock或spin_lock配對使用;

除此之外,還有一組自旋鎖使用於中斷情況下的api。

深入淺出Linux裝置驅動之字元裝置驅動程式

linux下的裝置驅動程式被組織為一組完成不同任務的函式的集合,通過這些函式使得windows的裝置操作猶如檔案一般。在應用程式看來,硬體裝置只是乙個裝置檔案,應用程式可以象操作普通檔案一樣對硬體裝置進行操作,如open close read write 等。linux主要將裝置分為二類 字元裝置和...

深入淺出 Linux裝置驅動中斷處理介紹

深入淺出 linux裝置驅動中斷處理介紹 與linux裝置驅動中中斷處理相關的首先是申請與釋放irq的api request irq 和free irq request irq 的原型為 int request irq unsigned int irq,void handler int irq,vo...

深入淺出 Linux裝置驅動非同步通知介紹

結合阻塞與非阻塞訪問 poll函式可以較好地解決裝置的讀寫,但是如果有了非同步通知就更方便了。非同步通知的意思是 一旦裝置就緒,則主動通知應用程式,這樣應用程式根本就不需要查詢裝置狀態,這一點非常類似於硬體上 中斷 地概念,比較準確的稱謂是 訊號驅動 sigio 的非同步i o 我們先來看乙個使用訊...