在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

淺談鴻蒙內(nèi)核源碼的信號(hào)量運(yùn)作原理

鴻蒙系統(tǒng)HarmonyOS ? 來(lái)源:my.oschina ? 作者: 鴻蒙內(nèi)核源碼分析 ? 2021-04-24 10:44 ? 次閱讀

基本概念

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

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ù)將被阻塞,從而保證了共享資源的互斥訪(fǎng)問(wèn)。另外,當(dāng)共享資源數(shù)為1時(shí),建議使用二值信號(hào)量,一種類(lèi)似于互斥鎖的機(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)量申請(qǐng)內(nèi)存(N值可以由用戶(hù)自行配置,通過(guò) LOSCFG_BASE_IPC_SEM_LIMIT 宏實(shí)現(xiàn)),并把所有信號(hào)量初始化成未使用,加入到未使用鏈表中供系統(tǒng)使用。

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

信號(hào)量申請(qǐng),若其計(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)量釋放,若沒(méi)有任務(wù)等待該信號(hào)量,則直接將計(jì)數(shù)器加1返回。否則喚醒該信號(hào)量等待任務(wù)隊(duì)列上的第一個(gè)任務(wù)。

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

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

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

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

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

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

#ifndef LOSCFG_BASE_IPC_SEM_LIMIT
#define LOSCFG_BASE_IPC_SEM_LIMIT 1024 //信號(hào)量的最大個(gè)數(shù)
#endif

LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)//信號(hào)量初始化
{
    LosSemCB *semNode = NULL;
    UINT32 index;

    LOS_ListInit(&g_unusedSemList);//初始
    /* system resident memory, don't free */
    g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信號(hào)池
    if (g_allSem == NULL) {
        return LOS_ERRNO_SEM_NO_MEMORY;
    }

    for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) {
        semNode = ((LosSemCB *)g_allSem) + index;//拿信號(hào)控制塊, 可以直接g_allSem[index]來(lái)嘛
        semNode->semID = SET_SEM_ID(0, index);//保存ID
        semNode->semStat = OS_SEM_UNUSED;//標(biāo)記未使用
        LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通過(guò)semList把 信號(hào)塊掛到空閑鏈表上
    }

    if (OsSemDbgInitHook() != LOS_OK) {
        return LOS_ERRNO_SEM_NO_MEMORY;
    }
    return LOS_OK;
}

分析如下:

初始化創(chuàng)建了信號(hào)量池來(lái)統(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來(lái)命名空閑鏈表,而此處使用unused,命名風(fēng)格不太嚴(yán)謹(jǐn),有待改善.

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

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

ERR_HANDLER:
    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)量

申請(qǐng)信號(hào)量

LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
{
    UINT32 intSave;
    LosSemCB *semPended = GET_SEM(semHandle);//通過(guò)ID拿到信號(hào)體
    UINT32 retErr = LOS_OK;
    LosTaskCB *runTask = NULL;

    if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
        OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID);
    }

    if (OS_INT_ACTIVE) {
        PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n");
        OsBackTrace();
        return LOS_ERRNO_SEM_PEND_INTERR;
    }

    runTask = OsCurrTaskGet();//獲取當(dāng)前任務(wù)
    if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
        OsBackTrace();
        return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK;
    }

    SCHEDULER_LOCK(intSave);

    if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) {
        retErr = LOS_ERRNO_SEM_INVALID;
        goto OUT;
    }

    /* Update the operate time, no matter the actual Pend success or not */
    OsSemDbgTimeUpdateHook(semHandle);

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

    if (!OsPreemptableInSched()) {//不能申請(qǐng)調(diào)度 (不能調(diào)度的原因是因?yàn)闆](méi)有持有調(diào)度任務(wù)自旋鎖)
        PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n");
        OsBackTrace();
        retErr = LOS_ERRNO_SEM_PEND_IN_LOCK;
        goto OUT;
    }

    runTask->taskSem = (VOID *)semPended;//標(biāo)記當(dāng)前任務(wù)在等這個(gè)信號(hào)量
    retErr = OsTaskWait(&semPended->semList, timeout, TRUE);//任務(wù)進(jìn)入等待狀態(tài),當(dāng)前任務(wù)會(huì)掛到semList上,并在其中切換任務(wù)上下文
    if (retErr == LOS_ERRNO_TSK_TIMEOUT) {//注意:這里是涉及到task切換的,把自己掛起,喚醒其他task 
        runTask->taskSem = NULL;
        retErr = LOS_ERRNO_SEM_TIMEOUT;
    }

OUT:
    SCHEDULER_UNLOCK(intSave);
    return retErr;
}

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

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

其余申請(qǐng)失敗的原因有:

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

中斷發(fā)生期間

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

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

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

無(wú)阻塞模式:即任務(wù)申請(qǐng)信號(hào)量時(shí),入?yún)imeout等于0。若當(dāng)前信號(hào)量計(jì)數(shù)值不為0,則申請(qǐng)成功,否則立即返回申請(qǐng)失敗。

永久阻塞模式:即任務(wù)申請(qǐng)信號(hào)量時(shí),入?yún)imeout等于0xFFFFFFFF。若當(dāng)前信號(hào)量計(jì)數(shù)值不為0,則申請(qǐng)成功。 否則該任務(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ù)申請(qǐng)信號(hào)量時(shí),0

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

釋放信號(hào)量

LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
{
    LosSemCB *semPosted = NULL;
    LosTaskCB *resumedTask = NULL;

    if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) {
        return LOS_ERRNO_SEM_INVALID;
    }

    semPosted = GET_SEM(semHandle);
    if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) {
        return LOS_ERRNO_SEM_INVALID;
    }

    /* Update the operate time, no matter the actual Post success or not */
    OsSemDbgTimeUpdateHook(semHandle);

    if (semPosted->semCount == OS_SEM_COUNT_MAX) {//當(dāng)前信號(hào)資源不能大于最大資源量
        return LOS_ERRNO_SEM_OVERFLOW;
    }
    if (!LOS_ListEmpty(&semPosted->semList)) {//當(dāng)前有任務(wù)掛在semList上,要去喚醒任務(wù)
        resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));//semList上面掛的都是task->pendlist節(jié)點(diǎn),取第一個(gè)task下來(lái)喚醒
        resumedTask->taskSem = NULL;//任務(wù)不用等信號(hào)了,重新變成NULL值
        OsTaskWake(resumedTask);//喚醒任務(wù),注意resumedTask一定不是當(dāng)前任務(wù),OsTaskWake里面并不會(huì)自己切換任務(wù)上下文,只是設(shè)置狀態(tài)
        if (needSched != NULL) {//參數(shù)不為空,就返回需要調(diào)度的標(biāo)簽
            *needSched = TRUE;//TRUE代表需要調(diào)度
        }
    } else {//當(dāng)前沒(méi)有任務(wù)掛在semList上,
        semPosted->semCount++;//信號(hào)資源多一個(gè)
    }

    return LOS_OK;
}

LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
{
    UINT32 intSave;
    UINT32 ret;
    BOOL needSched = FALSE;

    SCHEDULER_LOCK(intSave);
    ret = OsSemPostUnsafe(semHandle, &needSched);
        SCHEDULER_UNLOCK(intSave);
    if (needSched) {//需要調(diào)度的情況
        LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU發(fā)送調(diào)度指令
        LOS_Schedule();////發(fā)起調(diào)度
    }

    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)如下功能:

測(cè)試任務(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ù)中申請(qǐng)同一信號(hào)量,解鎖任務(wù)調(diào)度后兩任務(wù)阻塞,測(cè)試任務(wù)Example_TaskEntry釋放信號(hào)量。

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

Example_SemTask1定時(shí)阻塞模式申請(qǐng)信號(hào)量,等待時(shí)間為10Tick,因信號(hào)量仍被Example_SemTask2持有,Example_SemTask1掛起,10Tick后仍未得到信號(hào)量, Example_SemTask1被喚醒,試圖以永久阻塞模式申請(qǐng)信號(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ù)。

/* 任務(wù)ID */
static UINT32 g_testTaskId01;
static UINT32 g_testTaskId02;
/* 測(cè)試任務(wù)優(yōu)先級(jí) */
#define TASK_PRIO_TEST  5
/* 信號(hào)量結(jié)構(gòu)體id */
static UINT32 g_semId;

VOID Example_SemTask1(VOID)
{
    UINT32 ret;

    printf("Example_SemTask1 try get sem g_semId ,timeout 10 ticks.\n");
    /* 定時(shí)阻塞模式申請(qǐng)信號(hào)量,定時(shí)時(shí)間為10ticks */
    ret = LOS_SemPend(g_semId, 10);

    /*申請(qǐng)到信號(hào)量*/
    if (ret == LOS_OK) {
         LOS_SemPost(g_semId);
         return;
    }
    /* 定時(shí)時(shí)間到,未申請(qǐng)到信號(hào)量 */
    if (ret == LOS_ERRNO_SEM_TIMEOUT) {
        printf("Example_SemTask1 timeout and try get sem g_semId wait forever.\n");
        /*永久阻塞模式申請(qǐng)信號(hào)量*/
        ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
        printf("Example_SemTask1 wait_forever and get sem g_semId .\n");
        if (ret == LOS_OK) {
            LOS_SemPost(g_semId);
            return;
        }
    }
}

VOID Example_SemTask2(VOID)
{
    UINT32 ret;
    printf("Example_SemTask2 try get sem g_semId wait forever.\n");
    /* 永久阻塞模式申請(qǐng)信號(hào)量 */
    ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);

    if (ret == LOS_OK) {
        printf("Example_SemTask2 get sem g_semId and then delay 20ticks .\n");
    }

    /* 任務(wù)休眠20 ticks */
    LOS_TaskDelay(20);

    printf("Example_SemTask2 post sem g_semId .\n");
    /* 釋放信號(hào)量 */
    LOS_SemPost(g_semId);
    return;
}

UINT32 ExampleTaskEntry(VOID)
{
    UINT32 ret;
    TSK_INIT_PARAM_S task1;
    TSK_INIT_PARAM_S task2;

   /* 創(chuàng)建信號(hào)量 */
    LOS_SemCreate(0,&g_semId);

    /* 鎖任務(wù)調(diào)度 */
    LOS_TaskLock();

    /*創(chuàng)建任務(wù)1*/
    (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1;
    task1.pcName       = "TestTsk1";
    task1.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE;
    task1.usTaskPrio   = TASK_PRIO_TEST;
    ret = LOS_TaskCreate(&g_testTaskId01, &task1);
    if (ret != LOS_OK) {
        printf("task1 create failed .\n");
        return LOS_NOK;
    }

    /* 創(chuàng)建任務(wù)2 */
    (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2;
    task2.pcName       = "TestTsk2";
    task2.uwStackSize  = OS_TSK_DEFAULT_STACK_SIZE;
    task2.usTaskPrio   = (TASK_PRIO_TEST - 1);
    ret = LOS_TaskCreate(&g_testTaskId02, &task2);
    if (ret != LOS_OK) {
        printf("task2 create failed .\n");
        return LOS_NOK;
    }

    /* 解鎖任務(wù)調(diào)度 */
    LOS_TaskUnlock();

    ret = LOS_SemPost(g_semId);

    /* 任務(wù)休眠40 ticks */
    LOS_TaskDelay(40);

    /* 刪除信號(hào)量 */
    LOS_SemDelete(g_semId);

    /* 刪除任務(wù)1 */
    ret = LOS_TaskDelete(g_testTaskId01);
    if (ret != LOS_OK) {
        printf("task1 delete failed .\n");
        return LOS_NOK;
    }
    /* 刪除任務(wù)2 */
    ret = LOS_TaskDelete(g_testTaskId02);
    if (ret != LOS_OK) {
        printf("task2 delete failed .\n");
        return LOS_NOK;
    }

    return LOS_OK;
}

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

Example_SemTask2 try get sem g_semId wait forever.
Example_SemTask1 try get sem g_semId ,timeout 10 ticks.
Example_SemTask2 get sem g_semId and then delay 20ticks .
Example_SemTask1 timeout and try get sem g_semId wait forever.
Example_SemTask2 post sem g_semId .
Example_SemTask1 wait_forever and get sem g_semId .

編輯:hfy

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 鴻蒙系統(tǒng)
    +關(guān)注

    關(guān)注

    183

    文章

    2638

    瀏覽量

    66709
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    FreeRTOS信號(hào)量使用教程

    信號(hào)量是操作系統(tǒng)中重要的一部分,信號(hào)量一般用來(lái)進(jìn)行資源管理和任務(wù)同步, FreeRTOS中信號(hào)量又分為二值信號(hào)量、 計(jì)數(shù)型信號(hào)量、互斥
    的頭像 發(fā)表于 12-19 09:22 ?3281次閱讀
    FreeRTOS<b class='flag-5'>信號(hào)量</b>使用教程

    信號(hào)量是什么?信號(hào)量怎么運(yùn)作

    信號(hào)量信號(hào)量簡(jiǎn)介二值信號(hào)量計(jì)數(shù)信號(hào)量應(yīng)用場(chǎng)景二值信號(hào)量怎么運(yùn)作計(jì)數(shù)
    發(fā)表于 01-05 08:09

    信號(hào)量和互斥信號(hào)量的相關(guān)資料分享

    二進(jìn)制信號(hào)量理解為java里的獨(dú)享鎖,計(jì)數(shù)形的看成類(lèi)似于共享鎖。信號(hào)量API函數(shù)OSSemCreateOSSemDel關(guān)于opt(我理解為模式),在源碼的上面說(shuō)明了。本人英語(yǔ)不太行。大概翻譯過(guò)來(lái)就是這個(gè)意思,,,emm,,用大白
    發(fā)表于 03-02 07:11

    簡(jiǎn)單介紹信號(hào)信號(hào)量

    信號(hào)量實(shí)際上是一種約定機(jī)制,在多任務(wù)內(nèi)核中普遍使用。信號(hào)量用于:控制共享資源的使用權(quán)(滿(mǎn)足互斥條件)標(biāo)志某事件的發(fā)生使兩個(gè)任務(wù)的行為同步。
    的頭像 發(fā)表于 05-25 10:14 ?9701次閱讀
    簡(jiǎn)單介紹<b class='flag-5'>信號(hào)</b>與<b class='flag-5'>信號(hào)量</b>

    你了解Linux 各類(lèi)信號(hào)量?

    內(nèi)核信號(hào)量與用戶(hù)信號(hào)量,用戶(hù)信號(hào)量分為POXIS信號(hào)量和SYSTEMV信號(hào)量,POXIS
    發(fā)表于 05-04 17:19 ?2540次閱讀
    你了解Linux 各類(lèi)<b class='flag-5'>信號(hào)量</b>?

    信號(hào)量和自旋鎖

    。??? Linux 使用的同步機(jī)制可以說(shuō)從2.0到2.6以來(lái)不斷發(fā)展完善。從最初的原子操作,到后來(lái)的信號(hào)量,從大內(nèi)核鎖到今天的自旋鎖。這些同步機(jī)制的發(fā)展伴隨 Linux從單處理器到對(duì)稱(chēng)多處理器的過(guò)度
    發(fā)表于 04-02 14:43 ?822次閱讀

    Linux IPC System V 信號(hào)量

    () //創(chuàng)建/獲取信號(hào)量集 semctl() //初始化信號(hào)量集 semop() //操作信號(hào)量
    發(fā)表于 04-02 14:46 ?347次閱讀

    uCOS信號(hào)量源碼的詳細(xì)資料分析

    本文檔的主要內(nèi)容詳細(xì)介紹的是uCOS信號(hào)量源碼的詳細(xì)資料分析。 信號(hào)量相關(guān)的函數(shù) 創(chuàng)建一個(gè)信號(hào)量,參數(shù)是信號(hào)量的初始值,創(chuàng)建成功返回值是
    發(fā)表于 06-17 17:38 ?7次下載
    uCOS<b class='flag-5'>信號(hào)量</b><b class='flag-5'>源碼</b>的詳細(xì)資料分析

    華為物聯(lián)網(wǎng)操作系統(tǒng) LiteOS內(nèi)核教程04-信號(hào)量

    1. LiteOS內(nèi)核信號(hào)量 1.1.信號(hào)量 在多任務(wù)操作系統(tǒng)中,不同的任務(wù)之間需要同步運(yùn)行,信號(hào)量功能可以為用戶(hù)提供這方面的支持。信號(hào)量
    發(fā)表于 03-12 17:06 ?1755次閱讀

    Linux信號(hào)量(2):POSIX 信號(hào)量

    上一章,講述了 SYSTEM V 信號(hào)量,主要運(yùn)行于進(jìn)程之間,本章主要介紹 POSIX 信號(hào)量:有名信號(hào)量、無(wú)名信號(hào)量。 POSIX 信號(hào)量
    的頭像 發(fā)表于 10-29 17:34 ?750次閱讀

    LINUX內(nèi)核信號(hào)量設(shè)計(jì)與實(shí)現(xiàn)

    控制路徑可以睡眠。我們從 LINUX內(nèi)核信號(hào)量最直觀的設(shè)計(jì)/實(shí)現(xiàn)出發(fā),通過(guò)一步步改進(jìn),揭示在x86平臺(tái)上完整的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn),然后探討在不同平臺(tái)上通用的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn)。
    發(fā)表于 01-14 16:55 ?18次下載

    LINUX內(nèi)核信號(hào)量設(shè)計(jì)與實(shí)現(xiàn)

    控制路徑可以睡眠。我們從 LINUX內(nèi)核信號(hào)量最直觀的設(shè)計(jì)/實(shí)現(xiàn)出發(fā),通過(guò)一步步改進(jìn),揭示在x86平臺(tái)上完整的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn),然后探討在不同平臺(tái)上通用的信號(hào)量設(shè)計(jì)/實(shí)現(xiàn)。
    發(fā)表于 01-14 16:55 ?5次下載

    FreeRTOS的二值信號(hào)量

    FreeRTOS中的信號(hào)量是一種任務(wù)間通信的方式,信號(hào)量包括:二值信號(hào)量、互斥信號(hào)量、計(jì)數(shù)信號(hào)量,本次實(shí)驗(yàn)只使用二值
    的頭像 發(fā)表于 02-10 15:07 ?1554次閱讀

    Free RTOS的計(jì)數(shù)型信號(hào)量

    上篇講解了二值信號(hào)量,二值信號(hào)量只能判斷有無(wú),而不能確定事件發(fā)生的次數(shù),因此我們?yōu)榱舜_定事件的次數(shù)引入了計(jì)數(shù)型信號(hào)量
    的頭像 發(fā)表于 02-10 15:29 ?1078次閱讀
    Free RTOS的計(jì)數(shù)型<b class='flag-5'>信號(hào)量</b>

    使用Linux信號(hào)量實(shí)現(xiàn)互斥點(diǎn)燈

    信號(hào)量常用于控制對(duì)共享資源的訪(fǎng)問(wèn),有計(jì)數(shù)型信號(hào)量和二值信號(hào)量之分。初始化時(shí)信號(hào)量值大于1的,就是計(jì)數(shù)型信號(hào)量,計(jì)數(shù)型
    的頭像 發(fā)表于 04-13 15:12 ?853次閱讀
    使用Linux<b class='flag-5'>信號(hào)量</b>實(shí)現(xiàn)互斥點(diǎn)燈
    主站蜘蛛池模板: 青草青青产国视频在线 | 四虎影院观看视频 | 日本免费人成黄页网观看视频 | 永久免费品色堂 | 国产美女视频黄a视频免费全过程 | 麦克斯奥特曼在线观看 | 色多多在线观看高清免费 | 亚洲啪啪免费视频 | 主人扒开腿揉捏花蒂调教cfh | 色综合久久中文综合网 | 福利午夜在线 | 亚洲国产成+人+综合 | 美女黄18以下禁止观看的网站 | 美欧毛片 | 欧美福利网| 亚洲视频福利 | 亚洲大香伊人蕉在人依线 | 久久免费视频网站 | 国产精品1区2区3区在线播放 | 久在草影院 | 日本免费不卡视频 | 天天操天天摸天天干 | 天天视频色 | 色激情小说 | free性欧美高清另类 | 天天色影 | 大桥未久加勒比女热大陆在线 | 美女写真mm爽爽爽 | 免看乌克兰a一级 | 5566在线观看 | 免费污视频在线 | 天天操操操操操操 | 日本高清视频wwww色 | 欧美国产在线一区 | 国产成人亚洲精品77 | 午夜福利123| 夜夜爱网站 | 免费人成年激情视频在线观看 | 黄视频福利 | 黄色大毛片 | 噜噜噜久久久 |