訊號量(
semaphore
)是乙個用來指示可用的資源並將可用資源的數量以數值的形式表示出來的物件。當使用一組資源時,訊號量用來實現互斥控制和同步。
utenux
提供了訊號量出來的
api,可以很方便地使用訊號量。
utenux
中,訊號量包含乙個資源計數(用來指示是否存在相應的資源以及資源的數量)和乙個等待訊號量的任務佇列。
當乙個任務返回
m個資源時,訊號量資源計數加
m。當乙個任務獲得
n個資源時,訊號量資源計數減
n。如果訊號量資源的數量不夠(進一步減少訊號量計數可能使其值變成負數),則嘗試獲取資源的任務進入等待狀態,直至下次有資源返回。等待訊號量資源的任務被置入訊號量佇列。
1
、建立訊號量:
idsemid=tk_cre_sem(t_csem*pk_csem);
t_csem
為訊號量結構體,定義如下:
typedef structt_csem t_csem;
訊號量的屬性可以用下面的表示式得到:
sematr:=(ta_tfifo||ta_tpri)|(ta_first||ta_cnt)| [ta_dsname]
ta_tfifo
任務按fifo
的順序排隊
ta_tpri
任務按優先順序順序排隊
ta_first
佇列中第乙個任務最先獲得資源
ta_cnt
請求越少的任務越先獲得資源
ta_dsname
設定ds
物件名
等待訊號量的任務的排隊順序可以設定成
ta_fifo
或ta_tpri
。ta_first
和ta_cnt
設定了獲取資源的先後順序
2、tk_sig_sem
用來釋放訊號量
提供乙個釋放訊號量的數目即可。如果沒有超過最大訊號量計數,釋放後,訊號量技術增加這個數目。
3、tk_wai_sem
用來申請訊號量。
關於訊號的量申請:
如果一次需要獲得多個訊號量,但是訊號量又不夠。比如我需要
3個訊號量,但剩餘的訊號量只有
1個。那麼用
tk_wai_sem
申請訊號量時候,不會改變訊號量計數,然後開始等待其他訊號量。
實驗驗證:
1、建立三個任務:任務a、b、c。其中任務
a需要三個訊號量,任務b需要
4個訊號量。任務
a的優先順序大於任務
b。任務
c為最低優先順序的空閒任務。
2、建立任務後,先啟動任務
b,任務
b先申請
4個訊號量。然後啟動任務a。
3、由於任務
a的優先順序高於任務
b,任務
b被中斷,任務
a開始執行。由於系統中沒有可用訊號量,任務
a申請訊號量失敗
進入等待狀態。
4、之後回到任務
b,任務
b釋放四個訊號量。此時,系統中有足夠的訊號量供任務
a使用,任務
a被喚醒。繼續執行。
5、任務
a執行一次之後進入休眠,任務
b開始執行。任務
b申請並獲得
4個訊號量,完成
led反轉。之後釋放訊號量進入休眠。
6、兩個任務都進入等待狀態,任務
c開始執行。任務
c是乙個死迴圈。用於防止
os沒有正在執行的任務而退出。
實驗**如下:
//本實驗中,訊號量代表開發板上的是個led
//任務b需要4個訊號量,控制led同時亮滅
//任務a需要3個訊號量,控制led1、2、3同時亮滅
#include
"semsample.h
"#include
void
semsampletaska(w stacd,vp exinf);
void
semsampletaskb(w stacd,vp exinf);
void
semsampletaskc(w stacd,vp exinf);
void semsampleputcnt(void
);static
id taskid_a;
static
id taskid_b;
static
id taskid_c;
static
id semid;
er semsample(
void)
ctsk.itskpri = 26
; ctsk.stksz = 256
; ctsk.task =semsampletaskb;
taskid_b = tk_cre_tsk(&ctsk);
if(taskid_b ctsk.itskpri = 28
; ctsk.stksz = 256
; ctsk.task =semsampletaskc;
taskid_c = tk_cre_tsk(&ctsk);
if(taskid_c //
建立乙個訊號量
csem.exinf =null;
csem.isemcnt = 4
; csem.maxsem = 4
; csem.sematr = ta_tfifo |ta_first;
semid = tk_cre_sem(&csem);
if(semid semsampleputcnt();
//啟動任務b
tk_sta_tsk(taskid_b,5
);
return
true;}
void
semsampletaska(w stacd,vp exinf)
tm_putstring((ub*)"
任務a開始釋放3個訊號量\n");
tk_sig_sem(semid,3);
semsampleputcnt();
tk_slp_tsk(
500);
} }void
semsampletaskb(w stacd,vp exinf)
else
tk_sig_sem(semid,4);
//任務迴圈
while(1)
else
}else
tk_slp_tsk(
200);
} }
//防止任務全部休眠導致os退出的空閒任務
void
semsampletaskc(w stacd,vp exinf)
}void semsampleputcnt(void
)
實驗時串列埠輸出資訊:
當前的可用訊號量數為: 4
當前的可用訊號量數為: 4
任務a開始申請3個訊號量
當前的可用訊號量數為: 0
start taska sucessfuly.
當前的可用訊號量數為: 1
任務a開始釋放3個訊號量
當前的可用訊號量數為: 4
當前的可用訊號量數為: 4
任務b開始申請4個訊號量
任務b成功獲得4個訊號量
當前的可用訊號量數為: 0
任務b成功釋放4個訊號量
this is in task c
當前的可用訊號量數為: 4
任務b開始申請4個訊號量
任務b成功獲得4個訊號量
當前的可用訊號量數為: 0
任務b成功釋放4個訊號量
當前的可用訊號量數為: 4
任務b開始申請4個訊號量
任務b成功獲得4個訊號量
當前的可用訊號量數為: 0
訊號量 二值訊號量
訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...
python訊號量 Python訊號量
python訊號量教程 訊號量是由作業系統管理的一種抽象資料型別,用於在多執行緒中同步對共享資源的使用。本質上說,訊號量是乙個內部資料,用於標明當前的共享資源可以有多少併發讀取。也可以簡單的理解為,訊號量是多把鎖,同時允許多個執行緒來更改資料,而 python訊號量與互斥鎖的關係 訊號量的乙個特殊用...
訊號 訊號量
訊號是由 系統或者程序傳送給目標程序的資訊,以通知目標程序某個狀態的改變或系統異常。linux訊號可以由如下條件產生 1 對於前台程序,使用者可以通過輸入特殊的終端字元來給它傳送訊號。比如輸入ctrl c通常或給程序傳送乙個中斷訊號 2 系統異常。比如浮點異常和非法記憶體段訪問。3 系統狀態變化 4...