java開發(fā)內(nèi)核:進程優(yōu)先級

更詳細的講解和代碼調(diào)試演示過程,請參看視頻
Linux kernel Hacker, 從零構(gòu)建自己的內(nèi)核

我們有了進程調(diào)度,目前來看,所有進程一律平等。我們的調(diào)度算法是遍歷每一個進程,然后給每一個進程一定的運行時間,然后再切換下一個進程。但實際運用上,進程間不會是平等的,有些進程承擔著比較重要的工作,因此,它有理由獲得更多的運行時間,例如內(nèi)核進程,一些進程不是很重要,同理,它就不應該占用過度的CPU資源。本節(jié),我們要引入進程優(yōu)先級的功能,讓優(yōu)先級高的進程獲得更多的運行機會。

首先我們需要改動的是對TASK結(jié)構(gòu)體的定義(multi_task.h):

struct TASK {
    int sel, flags;
    int priority;
    struct TSS32 tss;
};

我們增加了一個變量叫priority, 這個變量代表著進程的優(yōu)先級,同時也是進程運行的時間片,這個值越大,進程獲得的CPU運行時間就越多。TASK對象的相關(guān)處理函數(shù)也需要做相應改動,在multi_task.c中:

struct TASK  *task_init(struct MEMMAN *memman) {
....
    task = task_alloc();
    task->flags = 2;  //active
    task->priority = 100;
    taskctl->running = 1;
    taskctl->now = 0;
    taskctl->tasks[0] = task;
    load_tr(task->sel);
    task_timer = timer_alloc();
    timer_settime(task_timer, task->priority);
    return task;
....
}

void task_run(struct TASK *task, int priority) {
    if (priority > 0) {
        task->priority = priority;
    }

    task->flags = 2;
    taskctl->tasks[taskctl->running] = task;
    taskctl->running++;
    return;
} 

void task_switch(void) {
    struct TASK *task;

    if (taskctl->running >= 2) {
        taskctl->now++;
        if (taskctl->now == taskctl->running) {
            taskctl->now = 0;
        }

        task = taskctl->tasks[taskctl->now];
        timer_settime(task_timer, task->priority);        
        farjmp(0, taskctl->tasks[taskctl->now]->sel);
    }

    return;
}

每個任務(wù)分配時,它的優(yōu)先級會默認設(shè)置成100,也就是該任務(wù)能獲得1秒的運行時間。task_run多增加了一個參數(shù),也就是任務(wù)優(yōu)先級,當一個任務(wù)準備加入調(diào)度隊列時,需要指定它的優(yōu)先級,在task_switch中,任務(wù)切換時,我們通過timer_settime來設(shè)置任務(wù)的運行時間,大家可以看到,時鐘的長度設(shè)置為task->priority, 也就是說,任務(wù)的優(yōu)先級同時也是任務(wù)的CPU運行時間。

任務(wù)激活的相關(guān)代碼也需要做改動,任務(wù)可以對應一個數(shù)據(jù)隊列,當隊列有數(shù)據(jù)抵達時,隊列會把存儲在其中的任務(wù)加入調(diào)度隊列,這個功能的實現(xiàn)是在golobal_define.c中,因此,我們也需要做相應改動:

int fifo8_put(struct FIFO8 *fifo, unsigned char data) {
....
    if (fifo->task != 0) {
        if (fifo->task->flags != 2) {
            task_run(fifo->task, 0);
        }
    }
....
}

當任務(wù)重新被激活時,我們傳入的優(yōu)先級數(shù)值是0,根據(jù)task_run的實現(xiàn),當優(yōu)先級數(shù)值為0時,任務(wù)保持原有優(yōu)先級不變。最后需要改動的是主入口函數(shù),在write_vga_desktop.c中:

void CMain(void) {
....
for (i = 0; i < 2; i++) {
....
task_run(task_b[i], (i+1)*5);
...
}
....
}

我們?yōu)榈谝粋€任務(wù)分配的優(yōu)先級是5,第二個任務(wù)的優(yōu)先級是10,也就是第二個任務(wù)得到的CPU時間是第一個任務(wù)的2倍。將上面代碼編譯運行時可以得到下面結(jié)果:

這里寫圖片描述

我們可以看到,第二個窗口計數(shù)數(shù)值大概是第一個窗口的2倍,這是因為第二個窗口對應的進程獲得的CPU運行時間是第一個窗口兩倍的緣故。

本節(jié)代碼比較簡單,這是為了下一次實現(xiàn)更復雜的進程調(diào)度功能:優(yōu)先級隊列做準備的,通過視頻可以獲得更加詳細的代碼講解和演示效果。

更多技術(shù)信息,包括操作系統(tǒng),編譯器,面試算法,機器學習,人工智能,請關(guān)照我的公眾號:


這里寫圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容