為什麼使用spinlock的時候不能睡眠

2021-05-12 16:51:34 字數 850 閱讀 2308

跟蹤一下spin_lock(&mr_lock)的實現

#define spin_lock(lock) _spin_lock(lock)

#define _spin_lock(lock) __lock(lock)

#define __lock(lock) /

do while (0)

注意到「preempt_disable()」,這個呼叫的功能是「關搶占」(在spin_unlock中會重新開啟搶占功能)。從中可以看出,使 用自旋鎖保護的區域是工作在非搶占的狀態;即使獲取不到鎖,在「自旋」狀態也是禁止搶占的。了解到這,我想咱們應該能夠理解為何自旋鎖保護的**不能睡眠 了。試想一下,如果在自旋鎖保護的**中間睡眠,此時發生程序排程,則可能另外乙個程序會再次呼叫spinlock保護的這段**。而我們現在知道了即使 在獲取不到鎖的「自旋」狀態,也是禁止搶占的,而「自旋」又是動態的,不會再睡眠了,也就是說在這個處理器上不會再有程序排程發生了,那麼死鎖自然就發生 了。

導致死鎖的過程:

[pid] action    ...... comment

[1]   關搶占

[1]   獲得鎖

[1]   睡眠排程            ...... 儘管已經關閉了搶占,[1]依然可以通過主動呼叫schedule(), schedule_timeout()等主動讓出cpu,排程其它程序。

[2]   關搶占               ...... [1]已經關閉搶占,所以這裡相當於nop操作

[2]   獲得鎖失敗         ...... [1]已經獲得了鎖,並且還沒有釋放

[2]   反覆嘗試獲得鎖   ...... 由於關閉了搶占,已經沒人能夠終止這個反覆嘗試的操作了,所以這裡出現了死鎖

使用SqlParameter時引數為什麼要設定長度

sqlparameter的作用是用來傳參,以及防止sql語句注入的。以前在連線資料庫時,我都是像這樣做的。new sqlparameter name name d層 public class dao public datatable selectbyname string name dt sqlhe...

為什麼在定義hashcode時要使用31這個數呢?

public int hashcode hash h return h 該函式是我看的函式介面原始碼,為什麼要使用31這個數呢?其實上面的實現也可以總結成數數裡面下面這樣的公式 s 0 31 n 1 s 1 31 n 2 s n 1 原因如下 a.31是乙個素數,素數作用就是如果我用乙個數字來乘以這...

為什麼在定義hashcode時要使用31這個數呢?

public int hashcode hash h return h 該函式是我看的函式介面原始碼,為什麼要使用31這個數呢?其實上面的實現也可以總結成數數裡面下面這樣的公式 s 0 31 n 1 s 1 31 n 2 s n 1 原因如下 a.31是乙個素數,素數作用就是如果我用乙個數字來乘以這...