“短进程优先”调度算法
Posted 呱呱呱?
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“短进程优先”调度算法相关的知识,希望对你有一定的参考价值。
实验一 进程调度
一、实验目的
编写并调试一个模拟的进程调度程序,以加深对进程的概念及进程调度算法的理解.
二、实验内容
- 调试运行“短进程优先”调度算法,给出运行结果。
- 采用“短进程优先”调度算法对五个进程进行调度。每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、到达时间、需要运行时间、已用CPU时间、进程状态等等。
- 每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。
三、实现思路
1. 变量声明与结构体定义
2. 输入函数
3. 所有进程结束后,输出所有进程信息
4. 找出运行时间最短的进程
5. 进程执行完毕
6. 主函数
四、主要的数据结构
1. 变量声明与结构体定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct pcb{
char name[10]; //进程名
int arrival_time; //进程到达时间()
int start_time; //进程开始时间
int need_time; //进程运行所需时间
int finish_time; //运行结束时间
struct pcb * link; //链接下一个pcb的指针
};
int num = 0; //输入的进程数
typedef struct pcb PCB; //定义结构体变量
/*
结构体指针p指向 每新建的一个进程
ready指针指向链表的第一个pcb
finish指针指向完成队列的第一个pcb结构体
*/
struct pcb *p = NULL, *ready = NULL, *finish = NULL;
2. 输入函数
//用来测试链表建立,输入链表结构体数据
void print_test(){
int i;
struct pcb * test = ready;
for(i=0;i<num;i++){
printf("\\n进程号:%d,进程名:%s,进程到达时间:%d,进程完成时间:%d",
i,test->name,test->arrival_time,test->need_time);
if(NULL != test->link){
test = test->link;
}
else{
printf("\\ntest_link end\\n");
}
}
}
//输入函数,建立链表
void input(){
int i;
struct pcb * q; //定义结构体变量
printf("请输入进程数:");
scanf("%d", &num);
for(i=0; i<num; i++){
printf("\\n进程号 NO.%d:", i);
p = (struct pcb*)malloc(sizeof(struct pcb));
printf("\\n输入进程名:");
scanf("%s", p->name);
printf("\\n请输入进程到达时间:");
scanf("%d", &p->arrival_time);
printf("\\n请输入进程运行时间:");
scanf("%d", &p->need_time);
p->link = NULL;
//建立链表
if(NULL == ready){ //建立第一个结构体,使指针p,q指向它
ready = p;
q = ready;
}
else{ //链表建立
q->link = p;
q = p;
}
printf("input success");
}
print_test(); //测试链表是否建立
}
3.所有进程结束后,输出所有进程信息
//输出当前运行进程相关数据或者打印暂无进程运行
void output(struct pcb * p, int now_time){
if(NULL == p){
printf("当前时刻:%d, 暂无进程在运行!\\n", now_time);
}
else{
printf("进程名:%s,到达时间:%d,运行需要时间:%d\\n",p->name,p->arrival_time,p->need_time);
}
}
- 4. 找出运行时间最短的进程
//sjf shortest job first最短作业优先
struct pcb * SJF(int now_time, int * after){
int min_time = 0; //最短时间,即优先运行的进程的时间
struct pcb * now_progress = NULL, *p = ready;
//遍历链表,查找出运行时间最短的进程
if (NULL != ready){
while(NULL != p){
if(now_time >= p->arrival_time){ //若进程已经到达,注意:时间单位为1
/*
min_time = p->need_time; //是错误的
now_progress = p;
if(p->need_time < min_time){
min_time = p->need_time;
now_progress = p;
} */
if(0 == min_time){ //给最短时间赋初值
now_progress = p;
min_time = p->need_time;
}
else{
if(p->need_time < min_time){
now_progress = p;
min_time = p->need_time;
}
}
}
p = p->link;
}
}
*after = min_time + now_time;
printf("\\nSJF:a shortest progress running!\\n");
return now_progress; //返回指向正在运行进程的指针
}
5. 进程执行完毕
//将已经运行完成的进程添加到finish队列,并且进程数减一
void destory(struct pcb * p, int now_time){
printf("destory start!\\n");
struct pcb * q = ready;
struct pcb * f = NULL; //用于finish链表的添加
if(strcmp(p->name, ready->name) == 0){ //若第一个进程完成
ready = ready->link;
}
//若中间或最后一个进程完成
else{
q = ready;
while((strcmp(q->link->name,p->name) != 0) && NULL != q->link){
q = q->link;
}
q->link = p->link;
}
p->finish_time = now_time; //结束时间
p->start_time = now_time - p->need_time; //开始时间
//将已经运行的进程添加到finish队列
if(NULL == finish){
finish = p; //finish指向完成链表的表头
p->link = NULL;
}
else{
f = finish;
while(NULL != f->link){
f = f->link;
}
f->link = p;
p->link = NULL;
}
num--; //进程数减一
printf("\\ndestory success!\\n");
}
主函数
int main(int argc, char *argv[]) {
input(); //调用输入函数
int now_time = 0; //初始时间为0
int after = 0; //执行完一个进程后的时间:优先运行进程的运行时间+当前时间
struct pcb * now_progress = NULL; //now_progress指向正在运行的进程(结构体)
struct pcb *m = NULL;
while(num > 0){ //进程数大于0,每次循环num会减一
printf("start SJF");
now_progress = SJF(now_time, &after); //调用SJF函数,遍历链表
if(NULL != now_progress){
/*进程执行,每循环一次,当前时间加一
同时要判断当前时间是否有进程刚好到达正在在等待 */
for(;now_time < after; now_time++){
printf("\\n当前时刻:%d", now_time);
printf("\\n-----------当前执行进程------------\\n");
output(now_progress, now_time); //调用output函数
printf("\\n-----------等待执行进程------------\\n");
m = ready;
while(NULL != m){ //循环,若当前时间有进程到达,打印相关信息
if(m != now_progress){
if(m->arrival_time <= now_time){
output(m, now_time);
printf("\\na new progress arrival\\n");
}
}
m = m->link;
}
}
//进程执行完后调用destory函数
destory(now_progress, now_time);
}
else{ //没有进程在运行
output(now_progress, now_time);
now_time++;
}
}
output_all();
return 0;
}
五、算法流程图
六、运行与测试(系统运行截图)
七、总结
SJF算法是以进程的运行时间长度作为优先级,进程运行时间越短,优先级越高。
缺点
必须预知进程的运行时间。即使是程序员也很难准确估计进程运行时间。如果估计过低,系统就可能按估计的时间终止进程的运行,但此时进程并未完成,故一般都会偏长估计
对长进程不利。长进程的周转时间会明显地增长。可怕的是,SJF算法完全忽视进程等待时间,可能使进程等待时间过长,出现饥饿现象。
人机无法实现交互。
完全未考虑进程的紧迫程度。不能保证紧迫性进程得到及时处理。
问题:对比说明短进程优先和动态优先数中PCB的定义有什么不同?
以上是关于“短进程优先”调度算法的主要内容,如果未能解决你的问题,请参考以下文章
操作系统| 作业调度算法平均周转时间平均带权周转时间先来先服务FCFS短作业优先SJF高优先权算法FPF高响应比优先算法HRRN
作业调度算法平均周转时间平均带权周转时间先来先服务FCFS短作业优先SJF高优先权(级)算法FPF高响应比优先算法HRRN