加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 什么是協(xié)程?
    • RTOS中協(xié)程與任務(wù)的區(qū)別
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

RTOS中協(xié)程與任務(wù)的區(qū)別

11/25 10:20
908
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

微信公眾號(hào) | strongerHuang

進(jìn)程和線程我們都很熟悉了,在RTOS系統(tǒng)中的叫法可能不一樣,我們熟悉的就是任務(wù)(Task),這個(gè)和線程(Thread)比較近似,你會(huì)發(fā)現(xiàn)有些地方RTOS的任務(wù),也叫線程。

但是在RTOS中還有一種不是那么常見(jiàn)的程序,叫協(xié)程。今天就來(lái)簡(jiǎn)單聊聊RTOS中協(xié)程和任務(wù)的內(nèi)容,以及它們的區(qū)別。

什么是協(xié)程?

協(xié)程,是協(xié)同程序的縮寫(xiě),英文名Coroutine。

協(xié)程是一種比線程更加輕量級(jí)的并發(fā)編程模型、程序組件,它允許單個(gè)線程內(nèi)執(zhí)行多個(gè)協(xié)程,而這些協(xié)程可以在執(zhí)行過(guò)程中掛起和恢復(fù),從而實(shí)現(xiàn)并發(fā)執(zhí)行的效果。

這里通過(guò)一張圖來(lái)了解下進(jìn)程、線程和協(xié)程的關(guān)系:

協(xié)程主要由三種狀態(tài):運(yùn)行(Runing)、就緒(Ready)、阻塞(Blocked)。

運(yùn)行:當(dāng)協(xié)程實(shí)際執(zhí)行時(shí),它被稱(chēng)為處于運(yùn)行狀態(tài),當(dāng)前協(xié)程正在使用處理器

就緒:就緒的協(xié)程是那些能夠執(zhí)行(未阻塞)但目前未執(zhí)行的協(xié)程。

阻塞:如果協(xié)程當(dāng)前正在等待時(shí)間事件或外部事件,則該協(xié)程被稱(chēng)為處于阻塞狀態(tài) 。

協(xié)程的函數(shù)結(jié)構(gòu):

void vACoRoutineFunction( CoRoutineHandle_t xHandle,                          UBaseType_t uxIndex ){    crSTART( xHandle );
    for( ;; )    {        //-- Co-routine application code here. --    }
    crEND();}

以調(diào)用 crSTART() 開(kāi)始,調(diào)用 crEND() 結(jié)束,協(xié)程函數(shù)不應(yīng)返回任何值。

它其實(shí)和RTOS中的任務(wù)有點(diǎn)類(lèi)似,但也有很多不同(最后說(shuō)區(qū)別)。

協(xié)程的案例

上面通過(guò)文字描述可能對(duì)于很多新手有點(diǎn)抽象,也有點(diǎn)難理解,這里結(jié)合代碼案例給大家描述協(xié)程。

1、創(chuàng)建一個(gè)簡(jiǎn)單的LED閃爍協(xié)程?

void vFlashCoRoutine( CoRoutineHandle_t xHandle,                      UBaseType_t uxIndex ){    crSTART( xHandle );
    for( ;; )    {????????//?延時(shí)一段時(shí)間        crDELAY( xHandle, 10 );
????????//?閃爍(翻轉(zhuǎn)LED)        vParTestToggleLED( 0 );    }
    crEND();}

2、調(diào)度協(xié)程

通過(guò)調(diào)用 vCoRoutineSchedule() 來(lái)調(diào)度協(xié)程。可以在任務(wù)空閑的時(shí)候:

void vApplicationIdleHook( void ){    vCoRoutineSchedule( void );}

或者在沒(méi)有執(zhí)行其他函數(shù)的時(shí)候,循環(huán)調(diào)用:

void vApplicationIdleHook( void ){    for( ;; )    {        vCoRoutineSchedule( void );    }}

3、創(chuàng)建協(xié)程并啟動(dòng)任務(wù)調(diào)度器

比如:在 main() 函數(shù)中創(chuàng)建并啟動(dòng)調(diào)度器。

#include "task.h"#include "croutine.h"
#define PRIORITY_0 0
void main( void ){????//?創(chuàng)建協(xié)程????xCoRoutineCreate(?vFlashCoRoutine,?PRIORITY_0,?0?);
????//啟用調(diào)度器.    vTaskStartScheduler();}

4、擴(kuò)展:使用索引參數(shù)

假設(shè)我們要從同一函數(shù)中創(chuàng)建 8 個(gè)這樣的協(xié)程。每個(gè)協(xié)程將 以不同速度閃爍不同的 LED。索引參數(shù)可用于在協(xié)程函數(shù)中區(qū)分協(xié)程。
這里,我們創(chuàng)建 8 個(gè)協(xié)程,并向每個(gè)協(xié)程傳遞不同的索引:

#include "task.h"#include "croutine.h"
#define PRIORITY_0        0#define NUM_COROUTINES    8
void main( void ){    int i;
    for( i = 0; i < NUM_COROUTINES; i++ )    {        // This time i is passed in as the index.        xCoRoutineCreate( vFlashCoRoutine, PRIORITY_0, i );    }
    // NOTE: Tasks can also be created here!
    // Start the RTOS scheduler.    vTaskStartScheduler();}

協(xié)程函數(shù)也被擴(kuò)展,因此每個(gè)協(xié)程使用的 LED 和閃爍速度都不同。

const int iFlashRates[ NUM_COROUTINES ] = { 10, 20, 30, 40, 50, 60, 70, 80 };const int iLEDToFlash[ NUM_COROUTINES ] = { 0, 1, 2, 3, 4, 5, 6, 7 }
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ){    crSTART( xHandle );
    for( ;; )    {????????//?根據(jù)索引設(shè)定延時(shí)        crDELAY( xHandle, iFlashRate[ uxIndex ] );
        // LED閃爍        vParTestToggleLED( iLEDToFlash[ uxIndex ] );????}    crEND();}

RTOS中協(xié)程與任務(wù)的區(qū)別

上面通過(guò)案例介紹的協(xié)程的內(nèi)容,有使用過(guò)RTOS(任務(wù))編程的朋友應(yīng)該都能看明白,其實(shí)任務(wù)和協(xié)程有很多相似之處,但也有很多區(qū)別:

1、調(diào)度和管理

任務(wù)由操作系統(tǒng)進(jìn)行調(diào)度和管理,而協(xié)程不需要系統(tǒng)調(diào)度器來(lái)管理,而是由用戶自己管理。

2、占用資源

任務(wù)通過(guò)系統(tǒng)調(diào)用,會(huì)占用更多系統(tǒng)資源,而協(xié)程在單個(gè)線程中執(zhí)行,不會(huì)像多線程那樣消耗大量的系統(tǒng)資源。

3、RAM使用量

協(xié)程不占用系統(tǒng)資源,因此協(xié)程更適合用于RAM較小的處理器,如早期的8位、16位MCU

4、限制

協(xié)程的優(yōu)勢(shì)是使用的 RAM 較少,但代價(jià)是協(xié)程存在更多的限制。與任務(wù)相比,協(xié)程的限制性更強(qiáng),使用起來(lái)也更復(fù)雜 。

5、執(zhí)行效率

由于協(xié)程的切換是由程序自身控制的,沒(méi)有線程切換的開(kāi)銷(xiāo),因此協(xié)程在執(zhí)行效率上通常更高。

6、......

早期,MCU資源和性能相對(duì)都不高,有些RTOS(如FreeRTOS)都有協(xié)程的功能。但是,隨著MCU資源和性能的提升,協(xié)程已經(jīng)被線程(任務(wù))替代了。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

作者黃工,從事嵌入式軟件開(kāi)發(fā)工作8年有余,高級(jí)嵌入式軟件工程師,業(yè)余維護(hù)公眾號(hào)『strongerHuang』,分享嵌入式軟硬件、單片機(jī)、物聯(lián)網(wǎng)等內(nèi)容。