spinlock與linux核心排程的關係

2021-09-08 14:41:35 字數 2419 閱讀 7992

華清遠見嵌入式學院

高階講師,arm公司授權atc講師。

關於自旋鎖用法介紹的文章,已經有很多,但有些細節的地方點的還不夠透。我這裡就把我個人認為大家容易有疑問的地方拿出來討論一下。

一、自旋鎖(spinlock)簡介

自旋鎖在同一時刻只能被最多乙個核心任務持有,所以乙個時刻只有乙個執行緒允許存在於臨界區中。這點可以應用在多處理機器、或執行在單處理器上的搶占式核心中需要的鎖定服務。

二、訊號量簡介

這裡也介紹下訊號量的概念,因為它的用法和自旋鎖有相似的地方。

linux中的訊號量是一種睡眠鎖。如果有乙個任務試圖獲得乙個已被持有的訊號量時,訊號量會將其推入等待佇列,然後讓其睡眠。這時處理器獲得自由去執行其它**。當持有訊號量的程序將訊號量釋放後,在等待佇列中的乙個任務將被喚醒,從而便可以獲得這個訊號量。

三、自旋鎖和訊號量對比

在很多地方自旋鎖和訊號量可以選擇任何乙個使用,但也有一些地方只能選擇某一種。下面對比一些兩者的用法。

表1-1自旋鎖和訊號量對比

應用場合

訊號量or自旋鎖

低開銷加鎖(臨界區執行時間較快)

優先選擇自旋鎖

低開銷加鎖(臨界區執行時間較長)

優先選擇訊號量

臨界區可能包含引起睡眠的**

不能選自旋鎖,可以選擇訊號量

臨界區位於非程序上下文時,此時不能睡眠

優先選擇自旋鎖,即使選擇訊號量也只能用down_trylock非阻塞的方式

四、自旋鎖與linux核心程序排程關係

我們討論下表1-1中的第3種情況(其它幾種情況比較好理解),如果臨界區可能包含引起睡眠的**則不能使用自旋鎖,否則可能引起死鎖。

那麼為什麼訊號量保護的**可以睡眠而自旋鎖就不能呢?

先看下自旋鎖的實現方法吧,自旋鎖的基本形式如下:

spin_lock(&mr_lock);

//臨界區

spin_unlock(&mr_lock);

跟蹤一下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保護的這段**。而我們現在知道了即使在獲取不到鎖的「自旋」狀態,也是禁止搶占的,而「自旋」又是動態的,不會再睡眠了,也就是說在這個處理器上不會再有程序排程發生了,那麼死鎖自然就發生了。

咱們可以總結下自旋鎖的特點:

●  單處理器非搶占核心下:自旋鎖會在編譯時被忽略;

●  單處理器搶占核心下:自旋鎖僅僅當作乙個設定核心搶占的開關;

●  多處理器下:此時才能完全發揮出自旋鎖的作用,自旋鎖在核心中主要用來防止多處理器中併發訪問臨界區,防止核心搶占造成的競爭。

五、linux搶占發生的時間

最後在了解下linux搶占發生的時間,搶占分為使用者搶占和核心搶占。

使用者搶占在以下情況下產生:

●  從系統呼叫返回使用者空間

●  從中斷處理程式返回使用者空間

核心搶占會發生在:

●  當從中斷處理程式返回核心空間的時候,且當時核心具有可搶占性;

●  當核心**再一次具有可搶占性的時候。(如:spin_unlock時)

●  如果核心中的任務顯式的呼叫schedule()

●  如果核心中的任務阻塞。

基本的程序排程就是發生在時鐘中斷後,並且發現程序的時間片已經使用完了,則發生程序搶占。通常我們會利用中斷處理程式返回核心空間的時候可以進行核心搶占這個特性來提高一些i/o操作的實時性,如:當i/o事件發生的是時候,對應的中斷處理程式被啟用,當它發現有程序在等待這個i/o事件的時候,它會啟用等待程序,並且設定當前正在執行程序的need_resched標誌,這樣在中斷處理程式返回的時候,排程程式被啟用,原來在等待i/o事件的程序(很可能)獲得執行權,從而保證了對i/o事件的相對快速響應(毫秒級)。可以看出,在i/o事件發生的時候,i/o事件的處理程序會搶占當前程序,系統的響應速度與排程時間片的長度無關。

spinlock與linux核心排程的關係

一 自旋鎖 spinlock 簡介 自旋鎖在同一時刻只能被最多乙個核心任務持有,所以乙個時刻只有乙個執行緒允許存在於臨界區中。這點可以應用在多處理機器 或執行在單處理器上的搶占式核心中需要的鎖定服務。二 訊號量簡介 這裡也介紹下訊號量的概念,因為它的用法和自旋鎖有相似的地方。linux中的訊號量是一...

spinlock與linux核心排程的關係

spinlock與linux核心排程的關係 一 自旋鎖 spinlock 簡介 自旋鎖在同一時刻只能被最多乙個核心任務持有,所以乙個時刻只有乙個執行緒允許存在於臨界區中。這點可以應用在多處理機器 或執行在單處理器上的搶占式核心中需要的鎖定服務。二 訊號量簡介 這裡也介紹下訊號量的概念,因為它的用法和...

spinlock與linux核心排程的關係

關於自旋鎖用法介紹的文章,已經有很多,但有些細節的地方點的還不夠透。我這裡就把我個人認為大家容易有疑問的地方拿出來討論一下。一 自旋鎖 spinlock 簡介 自旋鎖在同一時刻只能被最多乙個核心任務持有,所以乙個時刻只有乙個執行緒允許存在於臨界區中。這點可以應用在多處理機器 或執行在單處理器上的搶占...