• 操作系统开发系列—13.i.进程调度 ●


    上面的三个进程都是延迟相同的时间,让我们修改一下,尝试让它们延迟不同的时间。

    void TestA()
    {
    	int i = 0;
    	while (1) {
    		disp_str("A.");
    		milli_delay(300);
    	}
    }
    
    void TestB()
    {
    	int i = 0x1000;
    	while(1){
    		disp_str("B.");
    		milli_delay(900);
    	}
    }
    
    void TestC()
    {
    	int i = 0x2000;
    	while(1){
    		disp_str("C.");
    		milli_delay(1500);
    	}
    }
    

    运行后,数一数可以知道,输出中共有A字母140个,B字母51个,C字母32个,所以A和B的个数之比是2.745,A和C的个数之比是4.345,这两个数字与3(进程B和A的延迟时间之比)和5(进程C和A的延迟时间之比)是基本吻合的。

    为进程表添加新的成员,proc.h:

    typedef struct s_proc {
    	STACK_FRAME regs;          /* process registers saved in stack frame */
    
    	u16 ldt_sel;               /* gdt selector giving ldt base and limit */
    	DESCRIPTOR ldts[LDT_SIZE]; /* local descriptors for code and data */
    
            int ticks;                 /* remained ticks */
            int priority;
    
    	u32 pid;                   /* process id passed in from MM */
    	char p_name[16];           /* name of the process */
    }PROCESS;
    

    在进程表中添加了两个成员:ticks是递减的,从某个初值到0.为了记住ticks的初值,我们另外定义一个变量priority,它是恒定不变的。当所有的进程ticks都变为0之后,再把各自的ticks赋值为priority,然后继续执行。

    ticks和priority最初赋值如下,main.c的kernel_main():

    	proc_table[0].ticks = proc_table[0].priority = 150;
    	proc_table[1].ticks = proc_table[1].priority =  50;
    	proc_table[2].ticks = proc_table[2].priority =  30;
    

    对于进程调度,我们可以单独写一个函数,叫做schedule(),放在proc.c中:

    PUBLIC void schedule()
    {
    	PROCESS* p;
    	int	 greatest_ticks = 0;
    
    	while (!greatest_ticks) {
    		for (p = proc_table; p < proc_table+NR_TASKS; p++) {
    			if (p->ticks > greatest_ticks) {
    				greatest_ticks = p->ticks;
    				p_proc_ready = p;
    			}
    		}
    
    		if (!greatest_ticks) {
    			for (p = proc_table; p < proc_table+NR_TASKS; p++) {
    				p->ticks = p->priority;
    			}
    		}
    	}
    }
    

    同时修改时钟中断处理函数,clock.c:

    PUBLIC void clock_handler(int irq)
    {
    	ticks++;
    	p_proc_ready->ticks--;
    
    	if (k_reenter != 0) {
    		return;
    	}
    
    	schedule();
    }
    

    同时我们将所有进程的延迟时间全改为相同的值,把所有milli_delay的参数改成200.

    make运行的结果发现,虽然各个进程延迟的时间都相同,但由于改变了它们的优先级,运行的时间明显不同,这说明我们的优先级策略生效了!

    但是,当前的A、B、C三个字母的个数之比是139:71:54,大体相当于2.57:1.31:1,与进程优先级5:1.67:1(15:5:3)相差比较大。为什么呢,首先修改各个进程,让它们各自打印一个当前的ticks。然后修改一下schedule(),加上几条打印语句等等后再次运行,

    修改clock_handler,clock.c:

    PUBLIC void clock_handler(int irq)
    {
    	ticks++;
    	p_proc_ready->ticks--;
    
    	if (k_reenter != 0) {
    		return;
    	}
    
    	if (p_proc_ready->ticks > 0) {
    		return;
    	}
    
    	schedule();
    
    }
    

    这样,在一个进程的ticks还没有变成0之前,其他进程就不会有机会获得执行。

    从运行结果可以明显看出,进程A先执行,然后是B,再然后是C,与原先有了很大的差别。原因在于进程A的ticks从150递减至0之后,才把控制权给B,B用完它的ticks(50)之后再给C,然后各自的ticks被重置,继续下一个类似的过程。可以看到,进程A在150ticks内执行8次循环,B在50ticks内执行3次循环,C在30ticks内执行2次循环。这样就很直观了。

    我们再把它们的优先级改小一点:

    	proc_table[0].ticks = proc_table[0].priority = 15;
    	proc_table[1].ticks = proc_table[1].priority =  5;
    	proc_table[2].ticks = proc_table[2].priority =  3;
    

    然后把各个进程的延迟时间改成10ms:

    void TestA()
    {
    	int i = 0;
    	while (1) {
    		disp_str("A.");
    		milli_delay(10);
    	}
    }
    

    运行结果如下,可以看出,现在打印出的字符的个数之比非常接近15:5:3:

    源码

  • 相关阅读:
    网络分析[3] 发布NAServer到ArcGIS for Server(以Server 10.4为例)
    Vuejs环境安装与工程建立【小白Windows向】
    【C语言学习】-05 二维数组、字符串数组、多维数组
    【C语言学习】-04 一维数组、字符数组
    【C语言学习】-03 循环结构
    【C语言学习】-02 分支结构
    【C语言学习】-01 C基础
    ios layoutsubView 何时被调用
    Xcode 断点调试,取消直接进入到汇编语言界面处理
    一步一步实现iOS应用PUSH功能
  • 原文地址:https://www.cnblogs.com/joey-hua/p/5492561.html
Copyright © 2020-2023  润新知