信號(hào)量是另一種任務(wù)之間交互的機(jī)制,既可以用于控制對(duì)共享資源的訪問,也可用于任務(wù)間的同步(Synchronization)。 信號(hào)量的名字據(jù)說(shuō)來(lái)自鐵路系統(tǒng),用于確保一段鐵軌在一段時(shí)間內(nèi)只能有一列火車通過(guò)。這種互斥訪問是通過(guò)在指定的任何時(shí)間點(diǎn)上只設(shè)置一個(gè)方向的信號(hào)燈為綠燈,其他所有方向的信號(hào)燈都為紅燈來(lái)實(shí)現(xiàn)。在1965年,荷蘭學(xué)者Edsger Dijkstra據(jù)此提出了信號(hào)量的概念,用于不同線程之間的同步和共享資源的訪問。 信號(hào)量本質(zhì)上是一個(gè)單變量(非負(fù)整數(shù))的共享資源,如圖 1所示。
圖 1 信號(hào)量基本模型 對(duì)其有兩個(gè)基本操作:
操作過(guò)程參照?qǐng)D 2的例子。
圖 2 對(duì)信號(hào)量的操作 信號(hào)量?jī)H就其本身而言,沒有什么意義,只有與某些操作聯(lián)系起來(lái),才有意義。這些操作,可以是對(duì)某些共享資源的訪問,也可以是不同任務(wù)間的同步操作。用于不同的目的時(shí),信號(hào)量的初值和操作流程是不同的。 首先如果信號(hào)量是一個(gè)二值變量,只能取值0或1,則根據(jù)初值的不同,可以用于任務(wù)間同步或?qū)蚕碣Y源的訪問控制。
圖 3 排他訪問流程
圖 4 二值信號(hào)量用于任務(wù)同步 在圖中,實(shí)線箭頭表示任務(wù)的執(zhí)行流程,虛線箭頭表示信號(hào)量值的改變過(guò)程,實(shí)線方框表示任務(wù)內(nèi)的代碼執(zhí)行,點(diǎn)劃線方框表示操作系統(tǒng)對(duì)當(dāng)前任務(wù)的調(diào)度操作,點(diǎn)劃線箭頭表示信號(hào)量觸發(fā)的調(diào)度動(dòng)作。 任務(wù)2為了執(zhí)行代碼段2,必須首先獲取信號(hào)量。但此時(shí)信號(hào)量的值為0(初值),因此操作系統(tǒng)將任務(wù)2掛起,等待其他任務(wù)釋放信號(hào)量。任務(wù)1在執(zhí)行完代碼段1以后,釋放信號(hào)量。此時(shí)信號(hào)量的當(dāng)前值為1,任務(wù)2獲取信號(hào)量成功,操作系統(tǒng)喚醒任務(wù)2,開始執(zhí)行代碼段2。因此,任務(wù)2的代碼段2總是在任務(wù)1的代碼段1之后執(zhí)行。使得兩個(gè)任務(wù)的動(dòng)作完美同步。 在上圖中,還可以看到,任務(wù)2只獲取信號(hào)量,任務(wù)1只釋放信號(hào)量??梢员WC在循環(huán)執(zhí)行中,上述同步動(dòng)作也得到遵守。而且,這與共享資源的排他訪問中必須成對(duì)出現(xiàn)獲取/釋放操作也完全不同。 信號(hào)量用戶同步的一個(gè)經(jīng)常的使用場(chǎng)景就是實(shí)現(xiàn)所謂的延時(shí)中斷處理(Deferred Interrupt Handler)。由于中斷處理函數(shù)一般運(yùn)行在CPU的特權(quán)級(jí)等高優(yōu)先級(jí)別,外部事件不能打斷,因此終端處理程序不能占用太長(zhǎng)的CPU運(yùn)行時(shí)間。如果外部事件引起的處理時(shí)間較長(zhǎng),可以將它分為兩個(gè)部分:與硬件相關(guān)的需要立即執(zhí)行的處理(如寄存器的重置、狀態(tài)變量的保存等),而將其他的處理移到高優(yōu)先級(jí)Task中執(zhí)行。而中斷處理程序和任務(wù)之間,采用信號(hào)量進(jìn)行同步。移到高優(yōu)先級(jí)任務(wù)中執(zhí)行的部分就是延時(shí)中斷處理。 在FreeRTOS中,為這兩類二值信號(hào)量準(zhǔn)備了不同的API:用于任務(wù)同步的叫二值信號(hào)量(Binary Semaphore),用于排他訪問的叫互斥鎖(Mutex)。 如果是一個(gè)多值信號(hào)量,同樣根據(jù)其初值的不同,可用于事件通知和資源管理。
如一個(gè)用戶定義的緩存管理系統(tǒng)。假設(shè)該緩存系統(tǒng)由10個(gè)緩存構(gòu)成,用戶任務(wù)調(diào)用申請(qǐng)函數(shù)(如BufReq())申請(qǐng)緩存,使用完后調(diào)用釋放函數(shù)(如BufRel())釋放緩存。這樣一個(gè)系統(tǒng)就可以用多值信號(hào)量來(lái)管理。信號(hào)量的初始值設(shè)為10,每分配出一個(gè)緩存,其值減1;每釋放一個(gè)緩存,其值加1。如果緩存的申請(qǐng)數(shù)小于10時(shí),則申請(qǐng)立即返回;如果申請(qǐng)數(shù)達(dá)到10,則新的申請(qǐng)任務(wù)就被掛起,直到有緩存被釋放。
|
|
來(lái)自: SDNUC > 《ARM(STM32)》