vxworks二進位訊號量實現互斥和同步

來源:互聯網
上載者:User
Wind核心中有二進位訊號量、計數訊號量和互斥訊號量三種類型,為了使應用程式具有可移植性,還提供了POSIX(可移植作業系統介面)訊號量。在Vxorks作業系統中,訊號量是實現任務同步的主要手段,也是解決任務同步問題的最佳選擇。

關於互斥的實現:
    使用二進位訊號量可以很方便的實現互斥,互斥是指多任務在訪問臨界資源時具有排他性。為使多個任務互斥訪問臨界資源,只需要為該資源設定一個訊號量,相當於一個令牌,哪個任務拿到這個令牌即有權使用該資源。把訊號量設為可用,然後將需要資源的任務的臨界代碼置於semTake()和SemGive()之間即可。
註明:

  1. 互斥中的訊號量與任務優先順序的關係:任務的調度還是按照任務優先順序進行,但是在使用臨界資源的時候只有一個任務獲得訊號量,也就是說還是按照任務優先順序來獲得訊號量從而訪問資源。只有當前使用資源的任務釋放訊號量SemGive(),其他任務按照優先順序獲得訊號量。
  2. 訊號量屬性中的參數為:SEM_Q_PRIORITY。而且在建立訊號量的時候必須把訊號量置為滿的SEM_FULL。即訊號量可用。
  3. 註:訊號量屬性指定任務阻塞在訊號量後的各任務排隊的隊列類型   (sem_q_priority   按照優先順序排隊   或者sem_q_fifo   按照先來先服務的順序排隊)   ,sem_delete_safe安全刪除屬性,允許任務優先順序安全倒置sem_inversion_safe 
    基本實現互斥模型:
    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);
}
以上例子雖然定了各個任務的優先順序,但加上訊號量可以實現同步,而且防止優先順序反轉出現。

2、  也可以實現反轉。有興趣的可以將以上優先順序改一下試試看。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.