Vxworks信号量分析
?
Vxworks信號量分析
?
Wind內核中有二進制信號量、計數信號量和互斥信號量三種類型,為了使應用程序具有可移植性,還提供了POSIX(可移植操作系統接口)信號量。在Vxorks操作系統中,信號量是實現任務同步的主要手段,也是解決任務同步問題的最佳選擇。
關于互斥的實現:
??? 使用二進制信號量可以很方便的實現互斥,互斥是指多任務在訪問臨界資源時具有排他性。為使多個任務互斥訪問臨界資源,只需要為該資源設置一個信號量,相當于一個令牌,哪個任務拿到這個令牌即有權使用該資源。把信號量設為可用,然后將需要資源的任務的臨界代碼置于semTake()和SemGive()之間即可。
注明:
1.?????? 互斥中的信號量與任務優先級的關系:任務的調度還是按照任務優先級進行,但是在使用臨界資源的時候只有一個任務獲得信號量,也就是說還是按照任務優先級來獲得信號量從而訪問資源。只有當前使用資源的任務釋放信號量SemGive(),其他任務按照優先級獲得信號量。
2.?????? 信號量屬性中的參數為:SEM_Q_PRIORITY。而且在創建信號量的時候必須把信號量置為滿的SEM_FULL。即信號量可用。
基本實現互斥模型:
SEM_ID? semMutex;
semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
task(void)
?????? {
semTake(semMutex,WAIT_FOREVER);//得到信號量,即相當于得到使用資源的令牌
//臨界區,某一個時刻只能由一個任務訪問;
semGive(semMutex);
}
關于任務同步的實現:
??? 同步即任務按照一定順序先后執行,為了實現任務A和B的同步,只需要讓任務A和B共享一個信號量,并設初始值為空,即不可用,將semGive()置于任務A之后,而在任務B之前插入semTake()即可.
說明:
1.?????? 還是討論和優先級的關系。由于信號量初始化為空,不可用,所以可能使得優先級反轉,即高優先級任務B在等待低優先級任務A釋放信號量。只有執行了信號量釋放語句semGive()后任務B得到信號量才能執行。
2.?????? 屬性參數的設置為SEM_Q_FIFO,SEM_EMPTY;
實現模式參考:
SEM_ID semSync;
semSync = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
taskA(void)
{
……….
semGive(semSync);?? //信號量釋放,有效。
}
taskB(void)
{
semTake(semSync,WAIT_FOREVER);? //等待信號量。
……..
}
使用信號量注意事項:
1.?????? 用途不同,信號量屬性和初始值不同;
2.?????? 互斥訪問資源使,semTake()和semGive()必須成對出現,且先后順序不能顛倒;
3.?????? 避免刪除那些其他任務正在請求的信號量。
應用:
1、? 確保任務優先級不反轉:
SEM_ID? semFs;
SEM_ID? semFss;
SEM_ID? semFex;
semFs = semBCreate (SEM_Q_FIFO , SEM_EMPTY);
semFss = semBCreate (SEM_Q_FIFO , SEM_EMPTY);
semFex = semBCreate (SEM_Q_FIFO , SEM_EMPTY);? //創建三個信號量
void t_imaGet(void)
{
??? printf("a?? ";
?? semGive(semFs);???????????? //釋放信號量
}
void t_imaJud(void)
{
?? semTake(semFs,WAIT_FOREVER);???? //確保優先級不反轉。
? printf("jj ";
? semGive(semFss);
}
void t_imaPro(void)
{
??? semTake(semFss,WAIT_FOREVER);
??? printf("rr";?
?? semGive(semFex);???
}
void t_imaExc(void)
{
???? semTake(semFex,WAIT_FOREVER);
???? printf("Y";?
}
void start(void)
{
? int tGetId,tJudId,tProId,tExcId;
? tGetId = taskSpawn("tPget",200,0,1000,(FUNCPTR)t_imaGet,1,0,0,0,0,0,0,0,0,0);????
? tJudId = taskSpawn("tPjud",201,0,1000,(FUNCPTR)t_imaJud,3,0,0,0,0,0,0,0,0,0);
? tProId = taskSpawn("tPpro",202,0,1000,(FUNCPTR)t_imaPro,3,0,0,0,0,0,0,0,0,0);
? tExcId = taskSpawn("tPexc",203,0,1000,(FUNCPTR)t_imaExc,3,0,0,0,0,0,0,0,0,0);
}
以上例子雖然定了各個任務的優先級,但加上信號量可以實現同步,而且防止優先級反轉出現。
?
總結
以上是生活随笔為你收集整理的Vxworks信号量分析的全部內容,希望文章能夠幫你解決所遇到的問題。