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

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

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

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

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

我們?cè)黾恿艘粋€(gè)變量叫priority, 這個(gè)變量代表著進(jìn)程的優(yōu)先級(jí),同時(shí)也是進(jìn)程運(yùn)行的時(shí)間片,這個(gè)值越大,進(jìn)程獲得的CPU運(yùn)行時(shí)間就越多。TASK對(duì)象的相關(guān)處理函數(shù)也需要做相應(yīng)改動(dòng),在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;
}

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

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

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

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

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

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

這里寫圖片描述

我們可以看到,第二個(gè)窗口計(jì)數(shù)數(shù)值大概是第一個(gè)窗口的2倍,這是因?yàn)榈诙€(gè)窗口對(duì)應(yīng)的進(jìn)程獲得的CPU運(yùn)行時(shí)間是第一個(gè)窗口兩倍的緣故。

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

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


這里寫圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容