成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

鴻蒙內(nèi)核源碼分析(信號(hào)量篇) | 信號(hào)量解決任務(wù)同步問題

系統(tǒng)
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com

[[392644]]

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

基本概念

信號(hào)量(Semaphore) 是一種實(shí)現(xiàn)任務(wù)間通信的機(jī)制,可以實(shí)現(xiàn)任務(wù)間同步或共享資源的互斥訪問。 一個(gè)信號(hào)量的數(shù)據(jù)結(jié)構(gòu)中,通常有一個(gè)計(jì)數(shù)值,用于對(duì)有效資源數(shù)的計(jì)數(shù),表示剩下的可被使用的共享資源數(shù),其值的含義分兩種情況:

[[392645]]

  • 0,表示該信號(hào)量當(dāng)前不可獲取,因此可能存在正在等待該信號(hào)量的任務(wù)。 正值,表示該信號(hào)量當(dāng)前可被獲取。

以同步為目的的信號(hào)量和以互斥為目的的信號(hào)量在使用上有如下不同:

  • 用作互斥時(shí),初始信號(hào)量計(jì)數(shù)值不為0,表示可用的共享資源個(gè)數(shù)。在需要使用共享資源前,先獲取信號(hào)量,然后使用一個(gè)共享資源,使用完畢后釋放信號(hào)量。這樣在共享資源被取完,即信號(hào)量計(jì)數(shù)減至0時(shí),其他需要獲取信號(hào)量的任務(wù)將被阻塞,從而保證了共享資源的互斥訪問。另外,當(dāng)共享資源數(shù)為1時(shí),建議使用二值信號(hào)量,一種類似于互斥鎖的機(jī)制。
  • 用作同步時(shí),初始信號(hào)量計(jì)數(shù)值為0。任務(wù)1獲取信號(hào)量而阻塞,直到任務(wù)2或者某中斷釋放信號(hào)量,任務(wù)1才得以進(jìn)入Ready或Running態(tài),從而達(dá)到了任務(wù)間的同步。

信號(hào)量運(yùn)作原理

信號(hào)量初始化,為配置的N個(gè)信號(hào)量申請內(nèi)存(N值可以由用戶自行配置,通過 LOSCFG_BASE_IPC_SEM_LIMIT 宏實(shí)現(xiàn)),并把所有信號(hào)量初始化成未使用,加入到未使用鏈表中供系統(tǒng)使用。

● 信號(hào)量創(chuàng)建,從未使用的信號(hào)量鏈表中獲取一個(gè)信號(hào)量,并設(shè)定初值。

● 信號(hào)量申請,若其計(jì)數(shù)器值大于0,則直接減1返回成功。否則任務(wù)阻塞,等待其它任務(wù)釋放該信號(hào)量, 等待的超時(shí)時(shí)間可設(shè)定。當(dāng)任務(wù)被一個(gè)信號(hào)量阻塞時(shí),將該任務(wù)掛到信號(hào)量等待任務(wù)隊(duì)列的隊(duì)尾。

● 信號(hào)量釋放,若沒有任務(wù)等待該信號(hào)量,則直接將計(jì)數(shù)器加1返回。否則喚醒該信號(hào)量等待任務(wù)隊(duì)列上的第一個(gè)任務(wù)。

● 信號(hào)量刪除,將正在使用的信號(hào)量置為未使用信號(hào)量,并掛回到未使用鏈表。

信號(hào)量允許多個(gè)任務(wù)在同一時(shí)刻訪問共享資源,但會(huì)限制同一時(shí)刻訪問此資源的最大任務(wù)數(shù)目。 當(dāng)訪問資源的任務(wù)數(shù)達(dá)到該資源允許的最大數(shù)量時(shí),會(huì)阻塞其他試圖獲取該資源的任務(wù),直到有任務(wù)釋放該信號(hào)量。

信號(hào)量長什么樣?

  1. typedef struct { 
  2.     UINT8 semStat; /**< Semaphore state *///信號(hào)量的狀態(tài) 
  3.     UINT16 semCount; /**< Number of available semaphores *///有效信號(hào)量的數(shù)量 
  4.     UINT16 maxSemCount;  /**< Max number of available semaphores *///有效信號(hào)量的最大數(shù)量 
  5.     UINT32 semID; /**< Semaphore control structure ID *///信號(hào)量索引號(hào) 
  6.     LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore *///等待信號(hào)量的任務(wù)隊(duì)列,任務(wù)通過阻塞節(jié)點(diǎn)掛上去 
  7. } LosSemCB; 

semList,這又是一個(gè)雙向鏈表, 雙向鏈表是內(nèi)核最重要的結(jié)構(gòu)體, 可前往 鴻蒙內(nèi)核源碼分析(總目錄) 查看雙向鏈表篇, LOS_DL_LIST像狗皮膏藥一樣牢牢的寄生在宿主結(jié)構(gòu)體上semList上掛的是未來所有等待這個(gè)信號(hào)量的任務(wù).

初始化信號(hào)量模塊

  1. #ifndef LOSCFG_BASE_IPC_SEM_LIMIT 
  2. #define LOSCFG_BASE_IPC_SEM_LIMIT 1024 //信號(hào)量的最大個(gè)數(shù) 
  3. #endif 
  4.  
  5. LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)//信號(hào)量初始化 
  6.     LosSemCB *semNode = NULL
  7.     UINT32 index
  8.  
  9.     LOS_ListInit(&g_unusedSemList);//初始 
  10.     /* system resident memory, don't free */ 
  11.     g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信號(hào)池 
  12.     if (g_allSem == NULL) { 
  13.         return LOS_ERRNO_SEM_NO_MEMORY; 
  14.     } 
  15.  
  16.     for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { 
  17.         semNode = ((LosSemCB *)g_allSem) + index;//拿信號(hào)控制塊, 可以直接g_allSem[index]來嘛 
  18.         semNode->semID = SET_SEM_ID(0, index);//保存ID 
  19.         semNode->semStat = OS_SEM_UNUSED;//標(biāo)記未使用 
  20.         LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通過semList把 信號(hào)塊掛到空閑鏈表上 
  21.     } 
  22.  
  23.     if (OsSemDbgInitHook() != LOS_OK) { 
  24.         return LOS_ERRNO_SEM_NO_MEMORY; 
  25.     } 
  26.     return LOS_OK; 

分析如下:

● 初始化創(chuàng)建了信號(hào)量池來統(tǒng)一管理信號(hào)量, 默認(rèn) 1024 個(gè)信號(hào)量

● 信號(hào)ID范圍從 [0,1023]

● 未分配使用的信號(hào)量都掛到了全局變量 g_unusedSemList 上.

小建議:鴻蒙內(nèi)核其他池(如進(jìn)程池,任務(wù)池)都采用free來命名空閑鏈表,而此處使用unused,命名風(fēng)格不太嚴(yán)謹(jǐn),有待改善.

創(chuàng)建信號(hào)量

  1. LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle) 
  2.     unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);//從未使用信號(hào)量池中取首個(gè) 
  3.     LOS_ListDelete(unusedSem);//從空閑鏈表上摘除 
  4.     semCreated = GET_SEM_LIST(unusedSem);//通過semList掛到鏈表上的,這里也要通過它把LosSemCB頭查到. 進(jìn)程,線程等結(jié)構(gòu)體也都是這么干的. 
  5.     semCreated->semCount = count;//設(shè)置數(shù)量 
  6.     semCreated->semStat = OS_SEM_USED;//設(shè)置可用狀態(tài) 
  7.     semCreated->maxSemCount = maxCount;//設(shè)置最大信號(hào)數(shù)量 
  8.     LOS_ListInit(&semCreated->semList);//初始化鏈表,后續(xù)阻塞任務(wù)通過task->pendList掛到semList鏈表上,就知道哪些任務(wù)在等它了. 
  9.     *semHandle = semCreated->semID;//參數(shù)帶走 semID 
  10.     OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); 
  11.     return LOS_OK; 
  12.  
  13. ERR_HANDLER: 
  14.     OS_RETURN_ERROR_P2(errLine, errNo); 

分析如下:

● 從未使用的空閑鏈表中拿首個(gè)信號(hào)量供分配使用.

● 信號(hào)量的最大數(shù)量和信號(hào)量個(gè)數(shù)都由參數(shù)指定.

● 信號(hào)量狀態(tài)由 OS_SEM_UNUSED 變成了 OS_SEM_USED

● semHandle帶走信號(hào)量ID,外部由此知道成功創(chuàng)建了一個(gè)編號(hào)為 *semHandle 的信號(hào)量

申請信號(hào)量

  1. LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) 
  2.     UINT32 intSave; 
  3.     LosSemCB *semPended = GET_SEM(semHandle);//通過ID拿到信號(hào)體 
  4.     UINT32 retErr = LOS_OK; 
  5.     LosTaskCB *runTask = NULL
  6.  
  7.     if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { 
  8.         OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); 
  9.     } 
  10.  
  11.     if (OS_INT_ACTIVE) { 
  12.         PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); 
  13.         OsBackTrace(); 
  14.         return LOS_ERRNO_SEM_PEND_INTERR; 
  15.     } 
  16.  
  17.     runTask = OsCurrTaskGet();//獲取當(dāng)前任務(wù) 
  18.     if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { 
  19.         OsBackTrace(); 
  20.         return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK; 
  21.     } 
  22.  
  23.     SCHEDULER_LOCK(intSave); 
  24.  
  25.     if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) { 
  26.         retErr = LOS_ERRNO_SEM_INVALID; 
  27.         goto OUT
  28.     } 
  29.  
  30.     /* Update the operate timeno matter the actual Pend success or not */ 
  31.     OsSemDbgTimeUpdateHook(semHandle); 
  32.  
  33.     if (semPended->semCount > 0) {//還有資源可用,返回肯定得成功,semCount=0時(shí)代表沒資源了,task會(huì)必須去睡眠了 
  34.         semPended->semCount--;//資源少了一個(gè) 
  35.         goto OUT;//注意這里 retErr = LOS_OK ,所以返回是OK的  
  36.     } else if (!timeout) { 
  37.         retErr = LOS_ERRNO_SEM_UNAVAILABLE; 
  38.         goto OUT
  39.     } 
  40.  
  41.     if (!OsPreemptableInSched()) {//不能申請調(diào)度 (不能調(diào)度的原因是因?yàn)闆]有持有調(diào)度任務(wù)自旋鎖) 
  42.         PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); 
  43.         OsBackTrace(); 
  44.         retErr = LOS_ERRNO_SEM_PEND_IN_LOCK; 
  45.         goto OUT
  46.     } 
  47.  
  48.     runTask->taskSem = (VOID *)semPended;//標(biāo)記當(dāng)前任務(wù)在等這個(gè)信號(hào)量 
  49.     retErr = OsTaskWait(&semPended->semList, timeout, TRUE);//任務(wù)進(jìn)入等待狀態(tài),當(dāng)前任務(wù)會(huì)掛到semList上,并在其中切換任務(wù)上下文 
  50.     if (retErr == LOS_ERRNO_TSK_TIMEOUT) {//注意:這里是涉及到task切換的,把自己掛起,喚醒其他task  
  51.         runTask->taskSem = NULL
  52.         retErr = LOS_ERRNO_SEM_TIMEOUT; 
  53.     } 
  54.  
  55. OUT
  56.     SCHEDULER_UNLOCK(intSave); 
  57.     return retErr; 

分析如下: 這個(gè)函數(shù)有點(diǎn)復(fù)雜,大量的goto,但別被它繞暈了,盯著返回值看. 先說結(jié)果只有一種情況下申請信號(hào)量能成功(即 retErr == LOS_OK)

  1. if (semPended->semCount > 0) {//還有資源可用,返回肯定得成功,semCount=0時(shí)代表沒資源了,task會(huì)必須去睡眠了 
  2.       semPended->semCount--;//資源少了一個(gè) 
  3.       goto OUT;//注意這里 retErr = LOS_OK ,所以返回是OK的  
  4.   } 

其余申請失敗的原因有:

● 信號(hào)量ID超出范圍(默認(rèn)1024)

● 中斷發(fā)生期間

● 系統(tǒng)任務(wù)

● 信號(hào)量狀態(tài)不對(duì),信號(hào)量ID不匹配

以上都是異常的判斷,再說正常情況下 semPended->semCount = 0時(shí)的情況,沒有資源了怎么辦? 任務(wù)進(jìn)入 OsTaskWait 睡眠狀態(tài),怎么睡,睡多久,由參數(shù) timeout 定 timeout 值分以下三種模式:

  • 無阻塞模式:即任務(wù)申請信號(hào)量時(shí),入?yún)?timeout 等于0。若當(dāng)前信號(hào)量計(jì)數(shù)值不為0,則申請成功,否則立即返回申請失敗。
  • 永久阻塞模式:即任務(wù)申請信號(hào)量時(shí),入?yún)?timeout 等于0xFFFFFFFF。若當(dāng)前信號(hào)量計(jì)數(shù)值不為0,則申請成功。 否則該任務(wù)進(jìn)入阻塞態(tài),系統(tǒng)切換到就緒任務(wù)中優(yōu)先級(jí)最高者繼續(xù)執(zhí)行。任務(wù)進(jìn)入阻塞態(tài)后,直到有其他任務(wù)釋放該信號(hào)量,阻塞任務(wù)才會(huì)重新得以執(zhí)行。
  • 定時(shí)阻塞模式:即任務(wù)申請信號(hào)量時(shí),0

在 OsTaskWait 中,任務(wù)將被掛入semList鏈表,semList上掛的都是等待這個(gè)信號(hào)量的任務(wù).

釋放信號(hào)量

  1. LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched) 
  2.     LosSemCB *semPosted = NULL
  3.     LosTaskCB *resumedTask = NULL
  4.  
  5.     if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) { 
  6.         return LOS_ERRNO_SEM_INVALID; 
  7.     } 
  8.  
  9.     semPosted = GET_SEM(semHandle); 
  10.     if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) { 
  11.         return LOS_ERRNO_SEM_INVALID; 
  12.     } 
  13.  
  14.     /* Update the operate timeno matter the actual Post success or not */ 
  15.     OsSemDbgTimeUpdateHook(semHandle); 
  16.  
  17.     if (semPosted->semCount == OS_SEM_COUNT_MAX) {//當(dāng)前信號(hào)資源不能大于最大資源量 
  18.         return LOS_ERRNO_SEM_OVERFLOW; 
  19.     } 
  20.     if (!LOS_ListEmpty(&semPosted->semList)) {//當(dāng)前有任務(wù)掛在semList上,要去喚醒任務(wù) 
  21.         resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));//semList上面掛的都是task->pendlist節(jié)點(diǎn),取第一個(gè)task下來喚醒 
  22.         resumedTask->taskSem = NULL;//任務(wù)不用等信號(hào)了,重新變成NULL值 
  23.         OsTaskWake(resumedTask);//喚醒任務(wù),注意resumedTask一定不是當(dāng)前任務(wù),OsTaskWake里面并不會(huì)自己切換任務(wù)上下文,只是設(shè)置狀態(tài) 
  24.         if (needSched != NULL) {//參數(shù)不為空,就返回需要調(diào)度的標(biāo)簽 
  25.             *needSched = TRUE;//TRUE代表需要調(diào)度 
  26.         } 
  27.     } else {//當(dāng)前沒有任務(wù)掛在semList上, 
  28.         semPosted->semCount++;//信號(hào)資源多一個(gè) 
  29.     } 
  30.  
  31.     return LOS_OK; 
  32.  
  33. LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) 
  34.     UINT32 intSave; 
  35.     UINT32 ret; 
  36.     BOOL needSched = FALSE
  37.  
  38.     SCHEDULER_LOCK(intSave); 
  39.     ret = OsSemPostUnsafe(semHandle, &needSched); 
  40.         SCHEDULER_UNLOCK(intSave); 
  41.     if (needSched) {//需要調(diào)度的情況 
  42.         LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU發(fā)送調(diào)度指令 
  43.         LOS_Schedule();////發(fā)起調(diào)度 
  44.     } 
  45.  
  46.     return ret; 

分析如下:

● 注意看在什么情況下 semPosted->semCount 才會(huì) ++ ,是在LOS_ListEmpty為真的時(shí)候,semList是等待這個(gè)信號(hào)量的任務(wù). semList上的任務(wù)是在OsTaskWait中掛入的.都在等這個(gè)信號(hào).

● 每次OsSemPost都會(huì)喚醒semList鏈表上一個(gè)任務(wù),直到semList為空.

● 掌握信號(hào)量的核心是理解 LOS_SemPend 和 LOS_SemPost

編程示例

本實(shí)例實(shí)現(xiàn)如下功能:

● 測試任務(wù)Example_TaskEntry創(chuàng)建一個(gè)信號(hào)量,鎖任務(wù)調(diào)度,創(chuàng)建兩個(gè)任務(wù)Example_SemTask1、Example_SemTask2,Example_SemTask2優(yōu)先級(jí)高于Example_SemTask1,兩個(gè)任務(wù)中申請同一信號(hào)量,解鎖任務(wù)調(diào)度后兩任務(wù)阻塞,測試任務(wù)Example_TaskEntry釋放信號(hào)量。

● Example_SemTask2得到信號(hào)量,被調(diào)度,然后任務(wù)休眠20Tick,Example_SemTask2延遲,Example_SemTask1被喚醒。

● Example_SemTask1定時(shí)阻塞模式申請信號(hào)量,等待時(shí)間為10Tick,因信號(hào)量仍被Example_SemTask2持有,Example_SemTask1掛起,10Tick后仍未得到信號(hào)量, Example_SemTask1被喚醒,試圖以永久阻塞模式申請信號(hào)量,Example_SemTask1掛起。

● 20Tick后Example_SemTask2喚醒, 釋放信號(hào)量后,Example_SemTask1得到信號(hào)量被調(diào)度運(yùn)行,最后釋放信號(hào)量。

● Example_SemTask1執(zhí)行完,40Tick后任務(wù)Example_TaskEntry被喚醒,執(zhí)行刪除信號(hào)量,刪除兩個(gè)任務(wù)。

  1. /* 任務(wù)ID */ 
  2. static UINT32 g_testTaskId01; 
  3. static UINT32 g_testTaskId02; 
  4. /* 測試任務(wù)優(yōu)先級(jí) */ 
  5. #define TASK_PRIO_TEST  5 
  6. /* 信號(hào)量結(jié)構(gòu)體id */ 
  7. static UINT32 g_semId; 
  8.  
  9. VOID Example_SemTask1(VOID) 
  10.     UINT32 ret; 
  11.  
  12.     printf("Example_SemTask1 try get sem g_semId ,timeout 10 ticks.\n"); 
  13.     /* 定時(shí)阻塞模式申請信號(hào)量,定時(shí)時(shí)間為10ticks */ 
  14.     ret = LOS_SemPend(g_semId, 10); 
  15.  
  16.     /*申請到信號(hào)量*/ 
  17.     if (ret == LOS_OK) { 
  18.          LOS_SemPost(g_semId); 
  19.          return
  20.     } 
  21.     /* 定時(shí)時(shí)間到,未申請到信號(hào)量 */ 
  22.     if (ret == LOS_ERRNO_SEM_TIMEOUT) { 
  23.         printf("Example_SemTask1 timeout and try get sem g_semId wait forever.\n"); 
  24.         /*永久阻塞模式申請信號(hào)量*/ 
  25.         ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); 
  26.         printf("Example_SemTask1 wait_forever and get sem g_semId .\n"); 
  27.         if (ret == LOS_OK) { 
  28.             LOS_SemPost(g_semId); 
  29.             return
  30.         } 
  31.     } 
  32.  
  33. VOID Example_SemTask2(VOID) 
  34.     UINT32 ret; 
  35.     printf("Example_SemTask2 try get sem g_semId wait forever.\n"); 
  36.     /* 永久阻塞模式申請信號(hào)量 */ 
  37.     ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); 
  38.  
  39.     if (ret == LOS_OK) { 
  40.         printf("Example_SemTask2 get sem g_semId and then delay 20ticks .\n"); 
  41.     } 
  42.  
  43.     /* 任務(wù)休眠20 ticks */ 
  44.     LOS_TaskDelay(20); 
  45.  
  46.     printf("Example_SemTask2 post sem g_semId .\n"); 
  47.     /* 釋放信號(hào)量 */ 
  48.     LOS_SemPost(g_semId); 
  49.     return
  50.  
  51. UINT32 ExampleTaskEntry(VOID) 
  52.     UINT32 ret; 
  53.     TSK_INIT_PARAM_S task1; 
  54.     TSK_INIT_PARAM_S task2; 
  55.  
  56.    /* 創(chuàng)建信號(hào)量 */ 
  57.     LOS_SemCreate(0,&g_semId); 
  58.  
  59.     /* 鎖任務(wù)調(diào)度 */ 
  60.     LOS_TaskLock(); 
  61.  
  62.     /*創(chuàng)建任務(wù)1*/ 
  63.     (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 
  64.     task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; 
  65.     task1.pcName       = "TestTsk1"
  66.     task1.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE; 
  67.     task1.usTaskPrio   = TASK_PRIO_TEST; 
  68.     ret = LOS_TaskCreate(&g_testTaskId01, &task1); 
  69.     if (ret != LOS_OK) { 
  70.         printf("task1 create failed .\n"); 
  71.         return LOS_NOK; 
  72.     } 
  73.  
  74.     /* 創(chuàng)建任務(wù)2 */ 
  75.     (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 
  76.     task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; 
  77.     task2.pcName       = "TestTsk2"
  78.     task2.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE; 
  79.     task2.usTaskPrio   = (TASK_PRIO_TEST - 1); 
  80.     ret = LOS_TaskCreate(&g_testTaskId02, &task2); 
  81.     if (ret != LOS_OK) { 
  82.         printf("task2 create failed .\n"); 
  83.         return LOS_NOK; 
  84.     } 
  85.  
  86.     /* 解鎖任務(wù)調(diào)度 */ 
  87.     LOS_TaskUnlock(); 
  88.  
  89.     ret = LOS_SemPost(g_semId); 
  90.  
  91.     /* 任務(wù)休眠40 ticks */ 
  92.     LOS_TaskDelay(40); 
  93.  
  94.     /* 刪除信號(hào)量 */ 
  95.     LOS_SemDelete(g_semId); 
  96.  
  97.     /* 刪除任務(wù)1 */ 
  98.     ret = LOS_TaskDelete(g_testTaskId01); 
  99.     if (ret != LOS_OK) { 
  100.         printf("task1 delete failed .\n"); 
  101.         return LOS_NOK; 
  102.     } 
  103.     /* 刪除任務(wù)2 */ 
  104.     ret = LOS_TaskDelete(g_testTaskId02); 
  105.     if (ret != LOS_OK) { 
  106.         printf("task2 delete failed .\n"); 
  107.         return LOS_NOK; 
  108.     } 
  109.  
  110.     return LOS_OK; 

實(shí)例運(yùn)行結(jié)果:

  1. Example_SemTask2 try get sem g_semId wait forever. 
  2. Example_SemTask1 try get sem g_semId ,timeout 10 ticks. 
  3. Example_SemTask2 get sem g_semId and then delay 20ticks . 
  4. Example_SemTask1 timeout and try get sem g_semId wait forever. 
  5. Example_SemTask2 post sem g_semId . 
  6. Example_SemTask1 wait_forever and get sem g_semId . 

參與貢獻(xiàn)

訪問注解倉庫地址

Fork 本倉庫 >> 新建 Feat_xxx 分支 >> 提交代碼注解 >> 新建 Pull Request

新建 Issue

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-09-07 07:53:42

Semaphore 信號(hào)量源碼

2020-11-05 09:59:24

Linux內(nèi)核信號(hào)量

2022-04-13 11:12:43

鴻蒙輕內(nèi)核信號(hào)量模塊操作系統(tǒng)

2021-05-31 20:30:55

鴻蒙HarmonyOS應(yīng)用

2010-04-21 16:50:31

Unix信號(hào)量

2010-04-21 16:25:13

Unix信號(hào)量

2010-04-21 16:42:48

Unix信號(hào)量

2010-04-21 15:37:38

Unix信號(hào)量

2020-09-25 07:34:40

Linux系統(tǒng)編程信號(hào)量

2024-07-25 11:53:53

2025-04-16 08:50:00

信號(hào)量隔離線程池隔離并發(fā)控制

2024-10-29 15:23:45

Python線程安全

2013-08-21 14:06:05

iOS隊(duì)列信號(hào)

2019-11-19 09:00:38

JavaAND信號(hào)量

2009-12-08 12:14:43

2010-03-17 16:36:10

Java信號(hào)量模型

2010-07-15 15:32:10

Perl線程

2010-04-21 17:10:25

Unix信號(hào)量

2016-11-23 16:08:24

Python處理器分布式系統(tǒng)

2017-05-11 14:05:25

Consul分布式信號(hào)量
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91av视频在线播放 | 亚洲视频 欧美视频 | 欧洲精品久久久久毛片完整版 | 国产精品a一区二区三区网址 | 精品视频免费在线 | 最新免费av网站 | 美女131mm久久爽爽免费 | 天堂在线91 | 国产精品免费大片 | 一级片免费视频 | 久久久久久久久久性 | 一二三四在线视频观看社区 | av免费网站在线观看 | 国产亚洲精品久久19p | 欧美成人a∨高清免费观看 老司机午夜性大片 | 欧产日产国产精品99 | 在线只有精品 | 蜜桃精品在线 | 在线午夜 | 欧美日韩在线一区 | 91麻豆精品国产91久久久更新资源速度超快 | 久久尤物免费一区二区三区 | 国产jizz女人多喷水99 | 国产精品成人免费 | 免费看国产一级特黄aaaa大片 | 五月天婷婷狠狠 | 伊人手机在线视频 | 色综合欧美 | 性视频网 | 精品一区二区三区电影 | 中文字幕第5页 | 午夜婷婷激情 | 一级黄色片一级黄色片 | 99精品欧美一区二区蜜桃免费 | 国产精久久久久久久 | 91av亚洲 | 福利成人| 精品综合 | 国产精品污www在线观看 | 性做久久久久久免费观看欧美 | 中文字幕在线精品 |