更詳細的講解和代碼調(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)照我的公眾號: