Linux裝置驅動中的併發控制 訊號量

2021-06-16 17:14:01 字數 2442 閱讀 1164

linux 裝置驅動中必須解決的乙個問題是多個程序對共享資源的併發訪問,併發訪問會導致競態。 

1、併發與競態

併發(concurrency)指的是多個執行單元同時、並行被執行,而併發的執行單元對共享資源(硬體資源和軟體上的全域性變數、靜態變數等)的訪問則很容易導致競態(race  conditions)。

在linux核心中,主要的競態發生於如下幾種情況:

(1)、對稱多處理器(smp)的多個cpu 

(2)、 cpu 內程序與搶占它的程序

(3)、中斷(硬中斷、軟中斷、tasklet、底半部)與程序之間 

解決競態問題的途徑是保證對共享資源的互斥訪問,所謂互斥訪問是指乙個執行單元在訪問共享資源的時候,其他的執行單元被禁止訪問。 

訪問共享資源的**區域稱為臨界區(critical  sections) ,臨界區需要以某種互斥機制加以保護。中斷遮蔽、原子操作、自旋鎖和訊號量等是 linux 裝置驅動中可採用的互斥途徑。 

2、訊號量的使用

訊號量(semaphore)是用於保護臨界區的一種常用方法,它的使用方式和自旋鎖類似。與自旋鎖相同,只有得到訊號量的程序才能執行臨界區**。但是,與自旋鎖不同的是,當獲取不到訊號量時,程序不會原地打轉而是進入休眠等待狀態。 

linux系統中與訊號量相關的操作主要有如下 4 種。 

1.定義訊號量 

下列**定義名稱為sem的訊號量。 

struct semaphore sem;  

2.初始化訊號量 

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

該函式初始化訊號量,並設定訊號量 sem 的值為 val。儘管訊號量可以被初始化為大於1的值從而成為乙個計數訊號量,但是它通常不被這樣使用。 

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)。 

此外,下面兩個巨集是定義並初始化訊號量的「快捷方式」 。 

declare_mutex(name)  

declare_mutex_locked(name) 

前者定義乙個名為 name 的訊號量並初始化為1,後者定義乙個名為 name 的訊號量並初始化為0。 

3.獲得訊號量 

void down(struct semaphore * sem); 

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

int down_interruptible(struct semaphore * sem);  

該函式功能與 down()類似,不同之處為,因為down()而進入睡眠狀態的程序不能被訊號打斷,而因為 down_interruptible()而進入睡眠狀態的程序能被訊號打斷,訊號

也會導致該函式返回,這時候函式的返回值非0。 

int down_trylock(struct semaphore * sem); 

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

在使用down_interruptible()獲取訊號量時,對返回值一般會進行檢查,如果非 0,通常立即返回-erestartsys,如: 

if (down_interruptible(&sem)) 

4.釋放訊號量 

void up(struct semaphore * sem); 

該函式釋放訊號量 sem,喚醒等待者。 

訊號量一般這樣被使用,如下所示: 

//定義訊號量 

declare_mutex(mount_sem); 

down(&mount_sem);//獲取訊號量,保護臨界區 

... 

critical section //臨界區 

... 

up(&mount_sem);//釋放訊號量 

如下** 給出了使用訊號量實現裝置只能被乙個程序開啟的例子:

1  static declare_mutex(***_lock);//定義互斥鎖 

2  3  static int ***_open(struct inode *inode, struct file *filp) 

4   

11  

12 static int ***_release(struct inode *inode, struct file *filp) 

13  

以上來自《linux裝置驅動開發詳解》對於使用到的內容以後在進步以完善

Linux 裝置驅動中的併發控制

是指作業系統中,乙個時間段中有幾個程式都處於啟動執行到執行完畢間,且這幾個程式都是同乙個處理器上執行,但任何乙個時間點只有乙個程式在處理機器上執行。併發容易導致競爭問題。是兩個或者多個程序同時訪問乙個資源,從而引起的資源錯誤。所謂的原子操作就是該作業系統不會在執行完畢前被任何其他任務或者事件打斷。也...

Linux 裝置驅動併發控制簡述

答案 在linux中會遇到多個程序對共享資源的併發訪問,併發訪問會導致競態的發生,所以需要併發控制機制。併發與競態是指多個執行單位同時並行的被執行,而併發的執行單位對共享資源的訪問很容易導致競態 2.1 對稱多處理器 smp系統 的多個cpu 多個cpu共用同一條系統匯流排,因此可以訪問共同的外設和...

Linux 裝置驅動併發控制例項

在前面的筆記中,學習了linux裝置驅動中的併發控制,其中有中斷遮蔽 原子操作 自旋鎖 訊號量 互斥體及完成量。這幾種併發控制的技術就是解決多程序或多cpu之間對共享資源的同時訪問引起的競態問題。它們之間根據各自的性質使用在不同的場合中,這裡就不重複的介紹了,下面來分析 linux裝置驅動開發詳解 ...