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

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:

源码

转载于:https://www.cnblogs.com/joey-hua/p/5492561.html

操作系统开发系列—13.i.进程调度 ●相关推荐

  1. 操作系统开发系列—13.g.操作系统的系统调用 ●

    在我们的操作系统中,已经存在的3个进程是运行在ring1上的,它们已经不能任意地使用某些指令,不能访问某些权限更高的内存区域,但如果一项任务需要这些使用指令或者内存区域时,只能通过系统调用来实现,它是 ...

  2. 微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示

    微信公众号开发系列-13.基于RDIFramework.NET框架整合微信开发应用效果展示 1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为 ...

  3. 操作系统开发系列—2.进入32位保护模式

    源码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 3 ...

  4. EOS智能合约开发系列(13): 多签合约代码分析(二)

    知识星球地址:https://t.zsxq.com/2zBaE6u 欢迎访问知识星球,并留言探讨.

  5. 漏刻有时API接口实战开发系列(13):小鹅通云服务PHP-API二维数组传参解决方案

    在使用小鹅通云服务API开发过程中,当传递二维数组时,后台总是提示The user id list must be an array.即传递的参数必须是数组. 文档请求标准格式 {"acce ...

  6. 微信公众号开发系列-玩转微信开发-目录汇总

    引言 最遗憾的不是把理想丢在路上,而是理想从未上路. 每一个将想法变成现实的人,都值得称赞和学习.致正在奔跑的您! 在现在这个无处不在的互联网背景下,各种应用已不再仅仅局限于网页或桌面应用了,IOS. ...

  7. 服务器开发系列(三)——Linux与Windows操作系统基础功能对比

    系列文章目录 服务器开发系列(一)--计算机硬件 服务器开发系列(二)--Jetson Xavier NX 文章目录 系列文章目录 前言 一.操作系统概述 二.Linux和Windows的应用场景 三 ...

  8. Threejs系列--13游戏开发--沙漠赛车游戏【使用效果合成器添加高级效果】

    Threejs系列--13游戏开发--沙漠赛车游戏[使用效果合成器添加高级效果] 序言 目录结构 代码一览 Blur.js代码 Glows.js代码 Application.js代码 代码解读 运行结 ...

  9. iOS开发系列--通知与消息机制

    http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣 ...

最新文章

  1. ASP.NET MVC 过滤器(一)
  2. 英语阅读推荐:使用AJAX+WF+LINQ制作Google IG式首页
  3. PWN-PRACTICE-BUUCTF-23
  4. c# 插入数据到 uniqueidentifier_每天5分钟用C#学习数据结构(16)二叉树 Part 2
  5. 如何准备 Java 初级和高级的技术面试
  6. Dennis Ritchie, father of Unix and C, dies
  7. 十套精美个人博客网站模板
  8. Centos重置密码
  9. 打包报错:Unable to find a single main class from the following candidates
  10. Linux_加密和安全详细介绍
  11. 感恩工作平台心得体会_感恩工作心得体会
  12. 怎样用C语言sinx的曲线长度,Javascript 绘制 sin 曲线过程附图
  13. 前端学习——HTML(一)
  14. 如何提取微信公众号文章里边的视频地址
  15. 什么是域名DNS?有什么用途?
  16. 微信和联通“闪婚” 首推微信“零流量”资费
  17. Android 水波纹效果实现并且适配API21以下
  18. (附源码)计算机毕业设计ssm大学生二手物品交易网站
  19. 通过智能网关搭建智慧杆可视对讲系统
  20. 四级准考证在电脑上什么格式

热门文章

  1. Android WebView字体放大
  2. 鸿蒙OS应用(HarmonyOS Application)开发常见示例源码
  3. ​寒武纪思元370系列与飞桨完成II级兼容性测试,联合赋能AI落地实践
  4. 化繁为简,我用”知晓推送”开发微信小程序订阅消息
  5. [jQuery.FQcomputer] 分期商城汇率计算器
  6. python经典教程游戏软件_手把手带领大家用Python来做经典游戏 — 贪吃蛇
  7. TFN全新推出的全功能 手持式频谱分析仪 RMT系列 不仅可干扰定位 还可路测
  8. 【无标题】这个怎么写
  9. 为什么要特征标准化及特征标准化方法
  10. 国产32层堆栈3D闪存2019年量产 2020年赶超国际