1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        查詢式協(xié)作多任務系統(tǒng)

        共 4366字,需瀏覽 9分鐘

         ·

        2024-06-17 07:33


        前言

        在計算機科學領域,任務調(diào)度和協(xié)作是關鍵的概念。雖然傳統(tǒng)的操作系統(tǒng)提供了各種任務調(diào)度算法和機制,但有時我們需要更靈活、個性化的任務管理方式。

        即使采用定時器實現(xiàn)時間片論法任務調(diào)度,但是也必須等單個完整的任務執(zhí)行完成后才能執(zhí)行下一個完整的任務。

        本文將介紹使用標準庫頭文件中的setjmplongjmp函數(shù)構建一個簡單的查詢式協(xié)作多任務系統(tǒng),無需使用定時器進行任務切換。

        setjmplongjmp是C語言標準庫頭文件<setjmp.h>中提供的函數(shù)。它們的功能是實現(xiàn)非局部跳轉,可以在程序的不同位置之間進行跳轉,類似于goto語句的擴展。這種非局部跳轉的能力為我們構建查詢式協(xié)作多任務系統(tǒng)提供了基礎。

        介紹

        setjmp和longjmp

        setjmp函數(shù)用于保存當前程序狀態(tài),創(chuàng)建一個可以供后續(xù)longjmp函數(shù)跳轉的上下文環(huán)境。在調(diào)用setjmp時,程序會記錄當前的程序計數(shù)器、寄存器和堆棧等狀態(tài)信息,并將這些信息保存在一個jmp_buf結構中。同時,setjmp函數(shù)返回0作為普通調(diào)用的返回值,并將jmp_buf作為標識符存儲起來。

        不同平臺的jmp_buf的類型定義不一樣,大概占用不到30個字節(jié),因為不同平臺的相關寄存器等不一樣,因此占用的大小也不同。

        longjmp函數(shù)則實現(xiàn)了對保存的上下文環(huán)境的跳轉操作。通過傳遞之前由setjmp函數(shù)保存的jmp_buf標識符,longjmp函數(shù)會將程序的狀態(tài)還原到對應的上下文環(huán)境,并且會返回到setjmp處繼續(xù)執(zhí)行。

        協(xié)作式

        在協(xié)作式多任務調(diào)度下,當前任務需要通過主動放棄時間片提供給其他任務運行,而并非是被其他任務搶占,因此這里面并沒有所謂的優(yōu)先級概念之分。

        雖然協(xié)作式?jīng)]有所謂的優(yōu)先級概念之分,但是可以通過一定的方式也能實現(xiàn)一個簡單的優(yōu)先級,比如當前任務主動放棄時間片后,查詢更高優(yōu)先級的任務運行。

        時間片論法任務調(diào)度只能等任務運行完成才會給下一個任務時間片運行,并不存在主動放棄時間片的功能。

        實現(xiàn)思路

        了解到setjmplongjmp的功能和原理后,我們能不能通過它們來構建一個任務調(diào)度算法和機制呢?
        雖然setjmp可以記錄當前的程序計數(shù)器、寄存器和堆棧等狀態(tài)信息,但是實現(xiàn)多任務切換時堆棧里面的數(shù)據(jù)是會發(fā)生變化的。

        jmp_buf只記錄堆棧指針,不記錄堆棧指針指向的數(shù)據(jù)內(nèi)容。

        因此,如果要實現(xiàn)多任務切換,則需要為每個任務分配一定的堆棧預留空間,由于不使用堆,因此可以只考慮棧分配即可。

        當前任務主動放棄時間片后,不斷查詢滿足條件需要執(zhí)行的其他任務。

        代碼實現(xiàn)

        創(chuàng)建任務,使用了setjmp函數(shù)。

        int cotOs_Creat(OsTask_cb pfnOsTaskEnter, size_t stack)
        {
            size_t oldsp;

            if (sg_OsInfo.taskNum >= COT_OS_MAX_TASK || sg_OsInfo.pfnGetTimerMs == NULL)
            {
                return -1;
            }

            COT_OS_GET_STACK(oldsp);
            COT_OS_SET_STACK(sg_OsInfo.stackTop);

            if (0 == setjmp(sg_OsInfo.tcb[sg_OsInfo.taskNum].env))
            {
                COT_OS_SET_STACK(oldsp);
                sg_OsInfo.tcb[sg_OsInfo.taskNum].pfnOsTaskEnter = pfnOsTaskEnter;
                sg_OsInfo.taskNum++;
                sg_OsInfo.stackTop -= stack;
            }
            else
            {
                sg_OsInfo.tcb[sg_OsInfo.taskId].pfnOsTaskEnter();
            }

            return 0;
        }

        放棄時間片,使用了longjmp,這里集成了時間等待功能,即放棄時間片的時長(即使時長減至0也要等待其他任務主動放棄時間片才會運行)

        void cotOs_WaitFor(uint32_t time)
        {
            uint32_t timer = sg_OsInfo.pfnGetTimerMs();
            setjmp(sg_OsInfo.tcb[sg_OsInfo.taskId].env);

            if (!(sg_OsInfo.pfnGetTimerMs() - timer > time))
            {
                sg_OsInfo.taskId++;

                if (sg_OsInfo.taskId >= sg_OsInfo.taskNum)
                {
                    sg_OsInfo.taskId = 0;
                }

                longjmp(sg_OsInfo.tcb[sg_OsInfo.taskId].env, 1);
            }
        }

        除了繼承時間等待功能外,還定義了一個等待條件的主動放棄放棄時間片功能,即條件不滿足時主動放棄時間片(即使條件滿足后也要等待其他任務主動放棄時間片才會運行)

        #define cotOs_WaitFor_Cond(cond)   do{\
                extern jmp_buf *cotOs_GetTaskEnv1(void);\
                setjmp((*cotOs_GetTaskEnv1()));\
                if (!(cond)){\
                    extern void cotOs_RunNextTask(void);\
                    cotOs_RunNextTask();\
                }\
            }while (0)

        代碼鏈接

        目前已完成在STM32板子上的查詢式協(xié)作多任務系統(tǒng):
        下載鏈接(點擊閱讀原文):

        https://gitee.com/cot_package/cot_os

        擴展

        setjmplongjmp除了實現(xiàn)一個多任務系統(tǒng)外,其實還可以有其他的用法,比如實現(xiàn)C++中的try catch拋出異常處理功能。

        由于其特性問題,在實際代碼中,特別是應用程序代碼上,建議少用setjmplongjmp,否則會影響代碼閱讀,當然,不排除封裝成一個特殊的功能外



        春招已經(jīng)開始啦,大家如果不做好充足準備的話,春招很難找到好工作。


        送大家一份就業(yè)大禮包,大家可以突擊一下春招,找個好工作!


        瀏覽 50
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            色婷婷激情综合网 | 国产真实露脸乱子伦 | 亚洲AV实录无码成人精品电影 | 在办公室狂cao丝袜老师h文 | 国产伦精品一区二区三区四区在线看 | 狠狠撸天天操 | 99久久免费精品国产在热线观 | 扒开腿挺进女警湿润的花苞视频 | 性爱二区| 中文字幕日韩乱伦 |