死結問題(deadlock)
要死結必須要滿足以下四個條件
1.Mutual exclusion:一個資源一次只能被一個process所使用
2.Hold and Wait: process取得一個資源之後等待其他的資源
3.No preemption:資源只能由process自己釋放,不能由其他方式釋放
4.Circular wait:每個process都握有另一個process請求的資源,導致每一個process都在等待另一個process釋放資源
一般而言,我們可以處理死結問題(deadlock problem)使用下列三個方式其中之一
1.我們可以使用一個協議(protocol)去預防或是避免死結(deadlocks),確定系統永遠不會進入死結狀態(deadlocked state)。
2.我們可以允許系統進入死結狀態(deadlocked state),然後偵測它,恢復它。
3.我們可以完全無視這些問題,假裝這些問題從來不曾發生過。
禁止中斷
為了實現死結的情形,我們模擬了一個情況,我們假設user context為A行程,interrupt context為B行程,A與B行程皆需要取得相同資源因此皆需要上鎖,當A行程取得鎖定後,中間突然發生中斷,也就是B行程發生,於是沒有禁止中斷的情形下,我們在鎖定情形下必須處理B,但是不幸的是B行程也是存取與A相同的資源,但是此資源已經被A上鎖了,因此B行程便必須無限等待下去,此狀況我們稱作死結,如果要解決這種狀況該怎麼呢?Linux kernel提供一組函式來避免在上鎖期間被中斷干擾:
void local_irq_save(unsigned long flags);
void local_irq_restore(unsigned long flags);
夾在這兩個函式之間的行為都會將目前會發生所有中斷忽略,等到離開這個區間才會開始恢復所有中斷狀態,如果使用spin_lock的話上述章節有提到可以直接使用這三個函式避免中斷
void spin_lock_irqsave(spinlock_k *lock,unsigned long flags);
void spin_lock_irq(spinlock_k *lock);
void spin_lock_bh(spinlock_k *lock);