C 語言實現任務調度器

一、介紹

調度器是常用的一種編程框架,也是操作系統的拆分多任務的核心,比如單片機的裸機程序框架,網絡協議棧的框架如 can 網關、485 網關等等,使用場合比較多,是做穩定產品比較常用的編程技術

二、原理

1、超級循環

void main()
{
 while(1)
 {
  task1();
  task2();
  ...
 }
}
123456789

2、時間片與時標

1)我們把 cpu 執行時間分成一段一段的,每一段時間稱爲時間片 2)時間片的時間計時由定時器完成,把定時器定的時間成爲時標

3、調度算法介紹

1)時間片輪轉調度 2)強佔試調度

4、注意事項

1)所有任務的執行時間不能超過時標的時間 2)任務中不能有任何阻塞,比如使用延時函數 3)任務中的延時或者長時間任務利用狀態機拆分成多段

三、任務調度代碼實現

這裏拿 linux 來測試 schduler.c

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//        頭文件區
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include "scheduler.h"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//        接口定義區
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MAX_TASKS 10
static volatile unsigned char cur_task_num = 0;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//        變量定義區
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static running_queue_def running_queue[MAX_TASKS] = {0};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//        函數定義區
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int create_task(const void (*fun)(), unsigned short period)
{
    unsigned char i;

 if(cur_task_num >= MAX_TASKS)
 {
  printf("over limit max_tasks\n");
  return -1;
 }
    running_queue[i].fun = fun;
    running_queue[i].period = period;
    running_queue[i].cnt = 0;
    
    cur_task_num++;
    return 0;
}

int scheduler_run()
{
    unsigned char i;
    for(i = 0; i < cur_task_num; i++)
    {
        if(running_queue[i].cnt > 0)
        {
            running_queue[i].cnt--;
        }
        else
        {
            running_queue[i].cnt = running_queue[i].period;
            running_queue[i].fun();
        }
    }

    return 0;
}

schduler.h

#ifndef __SCHEDULER_H
#define __SCHEDULER_H

typedef struct {
     void (*fun)();        //運行函數
     unsigned short period;//週期
        unsigned short cnt;
}running_queue_def;

int create_task(const void (*fun)(), unsigned short period);
int scheduler_run();

#endif

main.c

#include "scheduler.h"
#include <unistd.h>
#include <stdio.h>

void task1()
{
    printf("task1 run\n");
}

void task2()
{
    printf("task2 run\n");
}

int main()
{
    create_task(task1, 1000);
    create_task(task2, 2000);
    while(1)
    {
        scheduler_run();
        usleep(1000);
    }

    return 0;
}

編譯腳本

build.sh

echo "delet main"
rm -rf main
sleep 1

gcc main.c scheduler.c -o main  -w

echo "build ok "
./main

圖片

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/SE7etSgXrl1lA03e7axrYA