linux驅動(第八課,互斥,同步,併發控制)

2021-10-06 01:49:33 字數 1959 閱讀 6190

驅動雖然是執行在核心空間的,但是驅動是執行在程序上下文中的,

當系統中有多個程序併發的請求驅動的服務時,就會導致競態,所以驅動必須解決的問題就是對共享資源的訪問。

併發訪問會導致競態。

當核心的多條執行路徑同時訪問同乙個共享資源時,就會造成競態。

例如中斷isr的執行,或者多核cpu的不同cpu核的並行執行。

常見的共享資源有,全域性變數,共享記憶體,等等。

解決競態的方法是,保證對共享資源的互斥訪問。

訪問共享資源的**段,成為臨界**段。(critical section)

linux中提供了多種實現互斥的方法,包括

中斷遮蔽,原子操作,自旋鎖,訊號量,互斥體。

在驅動開發中,推薦使用的是spinlock和mutex。

mutex的實現依賴於spinlock,即,spinlock是更底層的互斥手段。

使用mutex和spinlock有如下基本原則:

1)當鎖不可得時,mutex的開銷是process context的切換時間,而spinlock的開銷是spin,所以,如果臨界**段很小,推薦使用spinlock,節省開銷。

2) mutex保護的臨界**段,可以包含引起阻塞的**,但是spinlock絕對禁止保護可能阻塞的**。阻塞意味著程序切換,如果程序被切換,而另乙個程序又試圖獲取spinlock,死鎖就會發生。

3)mutex存在與process context,所以,如果需要在isr或者sisr中使用,那麼只能使用spinlock,或者使用mutex_trylock()進行訪問,避免阻塞。

來看看具體的應用。

作為核心通訊的一種機制,互斥也是一種event driven communication。

所以,無論是spinlock還是mutex,都對應於乙個物件實體。

利用kernel提供的服務函式,對spinlock或者mutex的成員進行修改,並對程序進行相應的處理。

mutex會引起程序排程,

當mutex_lock核心服務被請求時,核心會檢查mutex的資料,並對程序進行排程和阻塞,然後修改mutex的資料。

當mutex_unlock核心服務被請求時,核心會檢查mutex的資料,並對關聯的阻塞程序進行喚醒,然後修改mutex的資料。

整個過程中,程序都只是和kernel進行通訊,kernel負責排程,程序間通過kernel間接實現互斥通訊。

spinlock不會引起程序排程,

當spin_lock核心服務被請求時,核心會檢查spinlock的資料,如果鎖不可得,程序自旋等待下一次測試。如果鎖可得,核心會修改spinlock的資料,並返回,執行後續的**。

當spin_unlock核心服務被請求時,核心會修改spinlock的資料,並返回,執行後續的**。

來看乙個具體的例子。

struct globalmem_dev;
dev中內嵌乙個cdev,為了實現互斥,dev中內嵌了乙個mutex。

當程序呼叫dev的driver時,首先去嘗試獲得這個mutex,這樣就可以防止多個程序併發呼叫driver,對mem訪問發生競態。

static struct globalmem_dev globalmem;

static int __init globalmem_dev_init()

module_init(globalmem_dev_init);

在驅動載入函式中,初始化了mutex.

static ssize_t globalmem_read(struct file* filp, char __user *buf, size_t size, loff_t* ppos)

static ssize_t globalmem_write(struct file* filp, char __user *buf, size_t size, loff_t* ppos)

在fops中,對訪問公共資源的**段,進行互斥保護。

字元裝置驅動第八課 互斥鎖

struct mutex lock 定義互斥鎖mutex init mutex 功能 阻塞式上互斥鎖,搶不到就一直阻塞 mutex lock struct mutex lock 功能 非阻塞式上互斥鎖,搶不到也會返回往下走 返回值 成功搶到鎖 1 沒搶到鎖 0 int mutex trylock s...

第八課 混合

第八課 混合 opengl中的混色 在opengl中實現混色的步驟類似於我們以前提到的opengl過程。接著設定公式,並在繪製透明物件時關閉寫深度快取。因為我們想在半透明的圖形背後繪製 物件。這不是正確的混色方法,但絕大多數時候這種做法在簡單的專案中都工作的很好。rui martins 的補充 正確...

第八課 陣列

1 宣告 int arr string str 2 分配空間 arr new int 5 3 宣告同時分配記憶體 int arr new int 5 4 初始化 int arr new int 5 int arr2 1 宣告 int arr string str 2 分配空間 1 直接為每一維分配空...