在linux中提供了一些機制用來避免競爭條件,當乙個臨界區的資料在多個函式之間被呼叫時,為了保護資料不被破壞,可以採用一定的機制來保護臨界區的資料,主要有自旋鎖spinlock、訊號量,互斥鎖。
第一種:首先說自旋鎖spinlock:
在linux中定義spinlock的方法很簡單,與普通的結構體定義方式是一樣的
spinlock_t spinlock = spin_lock_unlocked
乙個自旋鎖必須初始化才能被使用,可以通過在編譯階段通過巨集定義來實現,比如上面的spin_lock_unlocked,這個表示乙個沒有鎖定的自旋鎖。
同樣在執行階段可以使用spin_lock_init () 函式動態地初始化乙個自旋鎖,其函式原型如下:
spinlock_t spin_lock_init(spinlock_t lock);
進入臨界區之前,需要使用spin_lock巨集定義來鎖定自旋鎖,spin_lock巨集定義的**如下:#define spin_lock(lock) _spin_lock(lock)
這個巨集用來獲得lock的自旋鎖,如果
能夠立即獲得自旋鎖,則巨集立刻返回,否則,這個巨集一直等待下去,直到被其它執行緒釋放為止。
退出臨界區之前,需要使用spin_unlock巨集定義來釋放自旋鎖。spin_unlock巨集定義的**如下:#define spin_unlock(lock) _spin_unlock(lock)
這個巨集用來釋放lock的自旋鎖,當呼叫該巨集後,自旋鎖立刻被釋放。
在驅動程式中,有些裝置只允許開啟一次,那麼就需要乙個自旋鎖保護表示裝置開啟或者關閉的狀態的乙個變數flag,此處的flag為乙個臨界資源,如果不對其進行保護,當裝置頻繁的開啟時,就有可能出現錯誤的flag的狀態,所以必須對flag進行保護,其**如下:
int flag;
spinlock_t spinlock;
int dev_init(void)
int dev_open(struct inode *inode, struct file *filp)
flag++; //標識為「正在被使用」
spin_unlock(&spinlock);
……}//end of dev_open()
int dev_release(struct inode *inode, struct file *filp)
當條件不滿足時,spinlock會一直不斷的迴圈判斷條件是否滿足,如果滿足就解鎖,執行之後的**。會影響linux的系統的效能。所以自旋鎖不應長時間持有。它適合於短時間的輕量級的加鎖機制。
自旋鎖不能遞迴使用,它被設計成在不同程序或者函式之間同步。
第二種:訊號量
第三種互斥鎖
怎樣避免競爭條件?
程序間通訊主要研究以下幾個問題 1 程序如何把資訊傳遞給另乙個 2 在多個程序的活動中不會出現交叉 3 程序執行順序正確性 1 競爭條件,兩個或多個程序讀寫某些共享資料,最後結果取決於程序執行的精確時序,稱為競爭條件,包含競爭條件的程式會在極少數情況下出現錯誤。怎樣避免競爭條件?避免競爭現象,實際上...
一些避免競爭條件的例項
人們總是期望核心開發者確定和解決由核心控制路徑的交錯執行所引起的同步問題。但是,避免競爭條件是一項艱鉅的任務,因為這需要對核心的各個成分如何相互作用有乙個清楚的理解。為了直觀地認識核心內部到底是什麼樣子,需要提及前面博文中所定義同步技術的幾種典型應用場景。1 引用計數器 引用計數器廣泛地用在核心中以...
linux中的互斥途徑
可以使程序與程序間的併發不在發生 二 自旋鎖 1自旋鎖,2讀寫自旋鎖,3順序鎖,4rcu 1 自旋鎖實際是忙等待,當鎖不可用時,cpu一直迴圈執行,測試並設定鎖直到可用而取得鎖,在忙等是不可以做任何事,僅僅是等待,所以只有在占用鎖的時間極短的情況下使用才合理。2 自旋鎖可能導致系統鎖死 原因 1,遞...