当前位置:   article > 正文

操作系统进程调度实验报告_操作系统进程调度实验报告 系统要求用户先输入进程的数量,然后依次输入每个进程的

操作系统进程调度实验报告 系统要求用户先输入进程的数量,然后依次输入每个进程的

一、实验目的

        用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解

二、实验类别

        综合性实验。综合高级语言编程、进程调度模型、进程调度算法及数据结构等多方面的知识

三、实验示例

例题: 设计一个有 N个进程共行的进程调度程序

进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。

每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。

进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输

入的时间。

  进程的运行时间以时间片为单位进行计算。

  每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

  就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。

  如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。

  每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。   

重复以上过程,直到所要进程都完成为止。

调度算法的流程图如下 :

四、源代码

  1. #include "stdio.h"
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #define getpch(type) (type*)malloc(sizeof(type)) //分配type类型大小的空间
  5. #define NULL 0
  6. struct pcb { /* 定义进程控制块PCB */
  7. char name[10]; //进程名
  8. char state; //进程状态
  9. int super; //进程优先级
  10. int ntime; //进程总共需要运行的时间
  11. int rtime; //进程已经运行的时间
  12. struct pcb* link; //指向后继节点的指针
  13. }*ready=NULL,*p; //ready指针永远指向队列的第一个进程
  14. typedef struct pcb PCB;
  15. sort() /* 建立对进程进行优先级排列函数*/
  16. {
  17. PCB *first, *second; // 指针second指向队列中当前处理的进程,指针first指向second的前驱节点,指针p指向准备插入队列的进程;
  18. int insert=0; //判断是否
  19. if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/
  20. {
  21. p->link=ready; //p指向的进程优先级最高,要成为队列中新的队首节点,即ready要修改指向p;
  22. ready=p;
  23. }
  24. else /* 如果队列有至少一个进程,则进程比较优先级,插入适当的位置中*/
  25. {
  26. first=ready; // first指向队首节点;
  27. second=first->link; // second指向第2个节点;
  28. while(second!=NULL) //如果有第2个节点,即队列至少有2个节点;
  29. {
  30. if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/
  31. { /*插入到当前进程前面*/ //p指向的进程要插入到first和sencond之间,修改指针;
  32. p->link=second;
  33. first->link=p;
  34. second=NULL; //找到了进程插入的位置,把second设为NULL,退出while循环;
  35. insert=1; //insert为1表示p指向的进程插入在两个进程之间;
  36. }
  37. else /* 插入进程优先数最低,则插入到队尾*/
  38. {
  39. first=first->link; // 此时first指向原队列最后一个进程;
  40. second=second->link; //此时second为NULL;
  41. }
  42. }
  43. if(insert==0) first->link=p; // insert为0表示p指向的进程插入到队尾
  44. }
  45. }
  46. input() /* 建立进程控制块函数*/
  47. {
  48. int i,num;
  49. //clrscr(); /*清屏*/
  50. printf("\n 请输入进程号?"); //输入需要调度的进程数量
  51. scanf("%d",&num);
  52. for(i=0;i<num;i++) //依次输入每个进程控制块的信息;
  53. {
  54. printf("\n 进程号No.%d:\n",i);
  55. p=getpch(PCB);
  56. printf("\n 输入进程名:");
  57. scanf("%s",p->name);
  58. printf("\n 输入进程优先数:");
  59. scanf("%d",&p->super);
  60. printf("\n 输入进程运行时间:");
  61. scanf("%d",&p->ntime);
  62. printf("\n");
  63. p->rtime=0;p->state='w';
  64. p->link=NULL;
  65. sort(); /* 调用sort函数*/ //把新创建的进程按优先级插入到队列中;
  66. }
  67. }
  68. int space() //获取当前队列的长度,即需要调度的进程个数;
  69. {
  70. int l=0; PCB* pr=ready; //pr指向队列第一个进程,即对首进程
  71. while(pr!=NULL) //依次遍历整个队列,计算长度
  72. {
  73. l++; //是字符l,不是数字1,代表队列长度;
  74. pr=pr->link;
  75. }
  76. return(l);
  77. }
  78. disp(PCB * pr) /*建立进程显示函数,用于显示当前进程的信息*/
  79. {
  80. printf("\n qname \t state \t super \t ndtime \t runtime \n");
  81. printf("|%s\t",pr->name);
  82. printf("|%c\t",pr->state);
  83. printf("|%d\t",pr->super);
  84. printf("|%d\t",pr->ntime);
  85. printf("|%d\t",pr->rtime);
  86. printf("\n");
  87. }
  88. check() /* 建立进程查看函数 */ //查看当前队列中每个进程信息
  89. {
  90. PCB* pr;
  91. printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
  92. disp(p);
  93. pr=ready; // pr指向队列对首进程
  94. printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/
  95. while(pr!=NULL) //循环遍历队列中每个进程
  96. {
  97. disp(pr);
  98. pr=pr->link;
  99. }
  100. }
  101. destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
  102. {
  103. printf("\n 进程 [%s] 已完成.\n",p->name);
  104. free(p);
  105. }
  106. running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
  107. {
  108. (p->rtime)++; //p指向当前运行进程,即从原队列中的对首进程,运行次数加1,rtime表示已运行的时间片;
  109. if(p->rtime==p->ntime) //如果进程需要运行总时间ntime和已运行时间rtime相等,表示该进程已经运行完毕,需要撤销;
  110. destroy(); /* 调用destroy函数*/
  111. else //如果该进程没有运行完毕,则使它的优先级减1,状态变为就绪,重新按优先级顺序插入到队列中;
  112. {
  113. (p->super)--;
  114. p->state='w';
  115. sort(); /*调用sort函数*/
  116. }
  117. }
  118. main() /*主函数*/
  119. {
  120. int len,h=0; //len:队列进程的个数;h:进程调度的时间片次数
  121. char ch; // 获取getchar()函数的字符
  122. input(); //输入要处理进程控制块信息
  123. len=space(); //当前进程队列的长度,即要处理的进程数量
  124. while((len!=0)&&(ready!=NULL)) //若队列不为空,即还有进程需要处理;
  125. {
  126. ch=getchar(); //从键盘获取字符
  127. h++; // h:进程执行的时间片次数序号
  128. printf("\n The execute number:%d \n",h); //
  129. p=ready; // ready永远指向队列的对首进程,p此时也指向队列的对首进程,但该对首进程需要出队列以便运行,;
  130. ready=p->link; //原队列的第2个进程成为新的对首进程
  131. p->link=NULL; //原对首进程出队列后,没有后继;
  132. p->state='R'; //原对首进程出队列后状态变为执行;
  133. check(); //查看当前队列中所有进程的信息,即原对首进程出队列后
  134. running();//原对首进程运行
  135. printf("\n 按任一键继续......");
  136. ch=getchar();//从键盘获取字符
  137. }
  138. printf("\n\n 进程已经完成.\n");
  139. ch=getchar();//从键盘获取字符
  140. }

五、运行截图

 六、报告总结

        通过本次实验,进程动态调度的过程与人工分析的结果一致,基本达到预期的目标。通过用户自己定义进程号、进程名、进程优先数、进程运行时间。优先数高的进程先进入运行状态,其他进程则为就绪状态。若优先数高的进程运行一个时间片后仍需运行,则进入就绪状态,该进程优先数-1。若进程运行一个时间片后,已经达成所需要的运行时间,则该进程完成,进入完成状态。如果就绪队列里存有多个优先数相同的进程,则根据进程号先来先得的原则运行。

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/556703
推荐阅读
相关标签
  

闽ICP备14008679号