实验一 进程调度

任务一

一、实验名称

       进程调度-代码阅读并调试实验

二、实验目的

1、阅读下面源代码,完善程序中填空处内容。
2、阅读代码,写出调度算法、算法流程图和程序功能。
3、解释数据结构PCB的定义和作用。
4、为main()写出每行的注释。
5、调试并运行代码,写出结果。
进程调度源程序如下:

jingchendiaodu.cpp
#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
struct pcb { /* 定义进程控制块PCB */
char name[10];
char state;
int super;
int ntime;
int rtime;
struct pcb* link;
}*ready=NULL,*p;
typedef struct pcb PCB;   sort() /* 建立对进程进行优先级排列函数*/
{
PCB *first, *second;
int insert=0;
if((ready==NULL)||((p->super)>(ready->super))) /*1 就绪队列为空或p的优先级大于就绪队列中第一个的优先级 */
{
p->link=ready;
ready=p;
}
else /* 进程比较优先级,插入适当的位置中*/
{
first=ready;
second=first->link;
while(second!=NULL)
{
if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/
{ /*插入到当前进程前面*/
p->link=second;
first->link=p;
second=NULL;
insert=1;
} else /* 插入进程优先数最低,则插入到队尾*/
{
2 first=first->link ;
second=second->link;
}
}
if(insert==0) first->link=p;
}
} input() /* 建立进程控制块函数*/
{
int i,num;
clrscr(); /*清屏*/
printf("\n 请输入进程号?");
scanf("%d",&num);
for(i=0;i<num;i++)
{
printf("\n 进程号No.%d:\n",i);
p=getpch(PCB);
printf("\n 输入进程名:");
scanf("%s",p->name);
printf("\n 输入进程优先数:");
scanf("%d",&p->super);
printf("\n 输入进程运行时间:");
scanf("%d",&p->ntime);
printf("\n");
p->rtime=0;p->state='w';
p->link=NULL;
sort(); /* 调用sort函数*/
}
}
int space()
{
int l=0; PCB* pr=ready;
while(pr!=NULL)
{
l++;
pr=pr->link;
}
return(l);
}
disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{
printf("\n qname \t state \t super \t ndtime \t runtime \n");
printf("|%s\t",pr->name);
printf("|%c\t",pr->state);
printf("|%d\t",pr->super);
printf("|%d\t",pr->ntime);
printf("|%d\t",pr->rtime);
printf("\n");
} check() /* 建立进程查看函数 */
{
PCB* pr;
printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
disp(p);
pr=ready;
printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/
while(pr!=NULL)
{
disp(pr);
pr=pr->link;
}
}
destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
{
printf("\n 进程 [%s] 已完成.\n",p->name);
free(p);
}
running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
{
(p->rtime)++;
if(p->rtime==p->ntime)
destroy(); /* 调用destroy函数*/
else
{
(p->super)--;
p->state='w';
sort(); /*调用sort函数*/
}
} main() /*主函数*/
{
int len,h=0; //定义两个int类型的变量
char ch; //定义一个字符型变量
input(); //调用进程控制块函数,录入进程信息并排序
len=space(); //用len表示进程块数
while((len!=0)&&(ready!=NULL)) //当进程没有全部运行完时
{
ch=getchar(); //读取按任意键继续的“任意键”
h++; //执行次数加一
printf("\n The execute number:%d \n",h); //打印当前执行次数
p=ready; //p指向第一个就绪进程块
ready=p->link; //就绪指针指向p的下一个进程块
p->link=NULL; //将p的下一个进程块置为空
p->state='R'; //状态置为正在运行
check();//调用进程查看函数,打印进程调度信息
running(); //运行进程p
printf("\n 按任一键继续......"); //提示用户按任意键继续
ch=getchar(); //存储“任意键”字符
}
printf("\n\n 进程已经完成.\n"); //显示进程全部调度完成
ch=getchar();//存储“任意键”字符
}

三、实验过程

1、阅读下面源代码,完善程序中填空处内容。
已在上文作业调度源程序呈现
2、阅读代码,写出调度算法、算法流程图和程序功能。
(1)调度算法
采用动态优先级调度算法和先来先服务算法。 首先定义了进程控制块PCB,每一个进程控制块的信息有:进程名、状态、优先数、需要运行的时间和已经运行的时间,要求用户输入进程的名字、优先数和需要的运行时间。每个进程的状态是W(就绪)或R(运行)。
对于按进程优先数降序排好序的就绪队列,每一次优先级最高的进程获得CPU并运行一个时间片,结束后,runtime加1,如果runtime=ndtime,表示该进程已完成,则撤消该进程,否则优先数减1,然后把它插入就绪队列进行等待。
每进行一次进程调度都会打印一次当前正在运行的进程的信息和就绪队列中各个进程的信息。
每按一次任意键,就进行一次进程调度,直到所有进程都完成为止。
(2)算法流程图

(3)程序功能
模拟了动态优先级调度算法和先来先服务算法的过程,并利用进程控制块模拟作业加入就绪队列和进程撤销。

3、解释数据结构PCB的定义和作用。
(1)定义
PCB是为了便于系统描述和管理进程的运行,在OS的核心为每个进程专门定义的记录型数据结构,用来记录进程相关信息和管理进程运行。
(2)作用
PCB的作用是使一个在多道程序环境下不能独立运行的程序(含数据)成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。具体作用有:
(1)作为独立运行基本单位的标志,事实上,PCB已成为进程存在于系统中的唯一标志;
(2)能实现间断性运行方式;
(3)提供进程管理所需要的信息;
(4)提供进程调度所需要的信息;

                已在上文作业调度源程序呈现

6、调试并运行代码,写出结果。
输入进程信息如下:

进程调度结果如下:

四、实验总结

1、先来先服务算法(FCFS)按照进程变为就绪状态的先后次序分派CPU,比较有利于长作业,而不利于短作业(因为长作业能够长时间占据处理机);有利于CPU繁忙的作业,而不利于I/O繁忙的作业。

任务二

一、实验名称

     进程调度-代码阅读并调试实验

二、实验目的

1、编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对五个进程进行调度。
  “最高优先数优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。
  静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。
动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1。或者,进程等待的时间超过某一时限时增加其优先数的值,等等。
2、编写并调试一个模拟的进程调度程序,采用“轮转法”调度算法对五个进程进行调度。
  轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。
  简单轮转法的基本思想是:所有就绪进程按FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。

三、实验过程

1、“最高优先数优先”调度算法

首先定义了进程控制块PCB,每一个进程控制块的信息有:进程名、状态、优先数、需要运行的时间和已经运行的时间,要求用户输入5个进程的名字、优先数和需要的运行时间。每个进程的状态是W(就绪)或R(运行)。
对于按进程优先数降序排好序的就绪队列,每一次优先数最高的进程获得CPU并运行一个时间片,结束后,runtime加1,如果runtime=ndtime,表示该进程已完成,则撤消该进程,否则优先数减1,然后把它插入就绪队列进行等待。
每进行一次进程调度都会打印一次当前正在运行的进程的信息和就绪队列中各个进程的信息。
每按一次任意键,就进行一次进程调度,直到所有进程都完成为止
输入进程信息如下:

进程调度结果如下:


2、“轮转法”调度算法

首先定义了进程控制块PCB,每一个进程控制块的信息有:进程名、状态、连接下一个进程的指针、需要时间片数和占用的时间片,要求用户输入5个进程的名字、优先数、占用的时间片数和需要的时间片。每个进程的状态是W(就绪)或R(运行)。
所有就绪进程按FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。

输入进程信息如下:

进程调度结果如下:

四、实验总结

1、“最高优先数优先”调度算法  
每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
  进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

五、代码

1、“最高优先数优先”调度算法
#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NULL 0
#include<iostream>
using namespace std;
struct pcb   /* 定义进程控制块PCB */
{char name[10];char state;int super;int ntime;int rtime;struct pcb* link;
}*ready=NULL,*p;
typedef struct pcb PCB;sort() /* 建立对进程进行优先级排列函数*/
{PCB *first, *second;int insert=0;if((ready==NULL)||((p->super)>(ready->super))) /*1就绪队列为空或p的优先级大于就绪队列中第一个的优先级*/{p->link=ready;ready=p;}else /* 进程比较优先级,插入适当的位置中*/{first=ready;second=first->link;while(second!=NULL){if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/{/*插入到当前进程前面*/p->link=second;first->link=p;second=NULL;insert=1;}else /* 插入进程优先数最低,则插入到队尾*/{first=first->link;                  ;second=second->link;}}if(insert==0) first->link=p;}
}
input() /* 建立进程控制块函数 */
{int i;for(i=0; i<5; i++){printf("\n 进程号No.%d:\n",i);p=getpch(PCB);printf("\n 输入进程名:");scanf("%s",p->name);printf("\n 输入进程优先数:");scanf("%d",&p->super);printf("\n 输入进程运行时间:");scanf("%d",&p->ntime);printf("\n");p->rtime=0;p->state='w';p->link=NULL;sort(); /* 调用sort函数*/}
}int space()
{int l=0;PCB* pr=ready;while(pr!=NULL){l++;pr=pr->link;}return(l);
}disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
{printf("\n qname \t state \t super \t ndtime \t runtime \n");printf("|%s\t",pr->name);printf("|%c\t",pr->state);printf("|%d\t",pr->super);printf("|%d\t",pr->ntime);printf("|%d\t",pr->rtime);printf("\n");
}check() /* 建立进程查看函数 */
{PCB* pr;printf("\n **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/disp(p);pr=ready;printf("\n ****当前就绪队列状态为:\n"); /*显示就绪队列状态*/while(pr!=NULL){disp(pr);pr=pr->link;}
}destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
{printf("\n 进程 [%s] 已完成.\n",p->name);free(p);
}running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
{(p->rtime)++;if(p->rtime==p->ntime)destroy(); /* 调用destroy函数*/else{(p->super)--;p->state='w';sort(); /*调用sort函数*/}
}main() /*主函数*/
{int len,h=0;char ch;input();len=space();while((len!=0)&&(ready!=NULL)){ch=getchar();h++;printf("\n The execute number:%d \n",h);p=ready;ready=p->link;p->link=NULL;p->state='R';check();running();printf("\n 按任一键继续......");ch=getchar();}printf("\n\n 进程已经完成.\n");ch=getchar();
}
2、“轮转法”调度算法
#include<stdio.h>
#include<malloc.h>
enum process_status{READY , RUN , FINISH}; typedef struct pcb
{char process_tag[20] ; struct pcb *next ; int time_slice ; // 轮转时间片int take_cpu_time ; //占用CPU时间片数int process_time ; //进程所需时间片数process_status status ;
} PCB ;typedef struct
{PCB *run ; //当前运行的进程指针PCB *ready ; //当前准备队列的头指针PCB *tail ; //准备队列的队尾指针PCB *finish ; //完成队列的指针
} PCBC ;
void init_pcbc(PCBC *p)
{p->run = NULL ;p->ready = NULL ;p->tail = NULL ;p->finish = NULL ;
}void input_process(PCBC *pcbc)
{PCB *pcb ;pcb = (PCB*)malloc(sizeof(PCB)) ;printf("请输入进程标识符:") ;scanf("%s" , &pcb->process_tag) ;printf("输入格式为: (优先级,占用CPU时间片数,进程所需时间片数) : ") ;scanf("%d%d%d" , &pcb->time_slice , &pcb->take_cpu_time , &pcb->process_time) ;pcb->status = READY ; //初始化就绪状态//当就绪队列为空时if(pcbc->ready == NULL && pcbc->tail == NULL){pcbc->ready = pcbc->tail = pcb ;pcb->next = NULL ;}else{pcb->next = pcbc->tail->next ;pcbc->tail->next = pcb ;pcbc->tail = pcb ;}
}void print_log(PCBC *pcbc){PCB *ready , *finish ;ready = pcbc->ready ;finish = pcbc->finish ;printf("--------------------------------------------------  \n") ;printf("Run: \n") ;if(pcbc->run != NULL){printf("%s  %04d  %04d  %04d \n" , pcbc->run->process_tag ,pcbc->run->time_slice , pcbc->run->take_cpu_time , pcbc->run->process_time) ;}else{printf("Run is empty! \n") ;}printf("Ready:\n") ;while(ready != NULL){printf("%s  %04d  %04d  %04d \n" , ready->process_tag ,ready->time_slice , ready->take_cpu_time , ready->process_time) ;ready = ready->next ;}printf("Finish:\n") ;while(finish != NULL){printf("%s  %04d  %04d  %04d \n" , finish->process_tag ,finish->time_slice , finish->take_cpu_time , finish->process_time) ;finish = finish->next ;}}void run_pcbc_timeSlice(PCBC *xpcbc)
{PCBC *pcbc = xpcbc ;PCB *temp , *pre , *tail ;while(pcbc->ready != NULL){pcbc->run = pcbc->ready ; pcbc->ready = pcbc->ready->next ; //改变队首元素print_log(pcbc) ;pcbc->run->take_cpu_time += 1 ;pcbc->run->process_time -= 1 ;if(pcbc->run->process_time == 0){if(pcbc->finish == NULL){pcbc->finish = pcbc->run ;pcbc->finish->next = NULL ;tail = pcbc->finish ;}else{tail->next = pcbc->run ;tail = tail->next ;tail->next = NULL ;}}else{if(pcbc->run->time_slice == pcbc->run->take_cpu_time) //占用CPU时间片数到{pcbc->run->take_cpu_time = 0 ;pcbc->run->next = NULL ;pcbc->tail->next = pcbc->run ;pcbc->tail = pcbc->run ;if(pcbc->ready == NULL){pcbc->ready = pcbc->tail ;pcbc->ready->next = NULL ;}}else{pcbc->run->next = pcbc->ready ;pcbc->ready = pcbc->run ;}}}pcbc->run = NULL ;print_log(pcbc) ;
}
int main()
{PCBC *pcbc ; //创建进程控制块链 ;pcbc = (PCBC*)malloc(sizeof(PCBC)) ;init_pcbc(pcbc) ; //初始化进程控制块链for(int i = 0 ; i < 5 ; i++){input_process(pcbc) ; }printf("------------------------\n") ;run_pcbc_timeSlice(pcbc) ;return 0 ;
}

操作系统实验报告一 进程调度相关推荐

  1. 操作系统实验报告【太原理工大学】

    操作系统实验报告 温馨提示:仅供参考! 目录 操作系统实验报告 一.进程调度程序设计 1.程序清单 2.运行结果 3.分析总结 二.页式虚拟存储管理程序设计 1.程序清单 2.运行结果 3.分析总结 ...

  2. 实验报告Linux操作系统基本命令,linux操作系统实验报告全部.doc

    linux操作系统实验报告全部 计算机操作系统 实验报告 学 号:姓 名:提交日期:2014.12.15成 绩: 东北大学秦皇岛分校 [实验题目]熟悉Linux/UNIX操作系统[实验目的]1.熟悉L ...

  3. Linux进程的创建和父子进程同步,操作系统实验报告_Linux进程创建与通信.doc

    操作系统实验报告_Linux进程创建与通信 2011-2012学年第一学期 专 业: 班 级: 学 号: 姓 名:提交日期:2011年11月实验二 Linux进程创建与进程通信 [实验目的 1. 熟悉 ...

  4. 计算机操作系统安装实验报告,计算机操作系统实验报告.doc

    计算机操作系统实验报告.doc (12页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 计算机操作系统实验报告实验一一.实验目的 在单处理 ...

  5. 操作系统实验报告18:硬盘柱面访问调度算法

    操作系统实验报告18 实验内容 实验内容:硬盘调度. 编写 C 程序模拟实现课件 Lecture25 中的硬盘柱面访问调度算法 包括 FCFS.SSTF.SCAN.C-SCAN.LOOK.C-LOOK ...

  6. 操作系统实验报告17:请求页面置换算法

    操作系统实验报告17 实验内容 实验内容:虚拟存储管理. 编写一个 C 程序模拟实现课件 Lecture24 中的请求页面置换算法 包括FIFO.LRU (stack and matrix imple ...

  7. 操作系统实验报告16:CPU 调度

    操作系统实验报告16 实验内容 实验内容:CPU 调度. 讨论课件 Lecture19-20 中 CPU 调度算法的例子,尝试基于 POSIX API 设计一个简单调度器(不考虑资源竞争问题): 创建 ...

  8. 操作系统实验报告15:进程同步与互斥线程池

    操作系统实验报告15 实验内容 实验内容:进程同步. 内容1:编译运行课件 Lecture18 例程代码. Algorithms 18-1 ~ 18-9. 内容2:在 Lab Week 13 的基础上 ...

  9. 操作系统实验报告14:Peterson 算法

    操作系统实验报告14 实验内容 实验内容:Peterson 算法. 把 Lecture08 示例 alg.8-1~8-3 拓展到多个读线程和多个写线程,应用 Peterson 算法原理设计实现共享内存 ...

  10. 操作系统实验报告13:线程池简单实现

    操作系统实验报告13 实验内容 实验内容:设计实现一个线程池 (Thread Pool) 使用 Pthread API FIFO 先不考虑互斥问题 编译.运行.测试用例 实验环境 架构:Intel x ...

最新文章

  1. docker手册_Docker手册
  2. php 绘制圆角矩形,C#_C#画圆角矩形的方法,本文实例讲述了C#画圆角矩形 - phpStudy...
  3. 《转》VMware vSphere 5.1 学习系列之四:安装 SQL Server 数据库
  4. android gridview 中图片大小不一,android – Gridview及其图像不适合所有屏幕大小
  5. 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
  6. 【讨论贴】关于父实子虚的疑问???
  7. Thinkphp ajax分页
  8. IDEA 惊天 bug:进程已结束,退出代码 1073741819
  9. er图用什么软件_工艺流程图用什么软件做?规范实用的流程图工具
  10. Android Studio(16)---工程相关解析(各种文件,资源访问)
  11. windows电脑记事本怎么自由排序?
  12. 2020.12.28用isprime函数判断m是否为素数
  13. Wifi网络共享----Connectify 使用
  14. 快慢指针慢指针和快指针一定会相遇
  15. 也许有那么一天你会发现原来自己是个怪人
  16. 2022年4月16日,第9天
  17. TF 在ROS基本作用和简单介绍
  18. jemter web端录制
  19. 一个关于css中margin-right没有效果的问题
  20. SpringBoot秒杀系统

热门文章

  1. 毕业设计之校园一卡通管理系统的设计与实现
  2. 常见的shell命令
  3. Eclipse配置SVN教程
  4. 飞控硬件在环之GPS模拟器
  5. STM32+MFRC522完成IC卡号读取、密码修改、数据读写
  6. IDEA官方中文版插件
  7. 【Matlab免费安装】
  8. C#.NET开源反编译工具ILSpy下载
  9. redhat7 安装telnet服务
  10. C语言基础入门实例汇总(共65个案例)