操作系统原理与实验——实验三优先级进程调度

实验指南

运行环境:

Dev c++

算法思想: 

本实验是模拟进程调度中的优先级算法,在先来先服务算法的基础上,只需对就绪队列到达时间进行一次排序。第一个到达的进程首先进入CPU,将其从就绪队列中出队后。若此后队首的进程的到达时间大于上一个进程的完成时间,则该进程进入CPU,其开始时间即到达时间;否则如果上一个进程完成后,已经有多个进程到达,则需从已到达的进程中寻找到优先级最高的进程,并将其取出,进入CPU执行。直到所有进程执行完毕。

核心数据结构:

typedef struct data{

      int hour;

      int minute;

}time;

typedef struct node{

     

      int id;//进程编号

      char name[20];//进程名

      int good;//优先级

      time arrive;//到达就绪队列的时间

      int zx;//执行时间

      time start;//开始执行时间

      time finish;//执行完成时间

      int zz;//周转时间=执行完成时间-到达就绪队列时间

      float zzxs;//带权周转时间=周转时间/执行时间

      struct node* next;

     

}Node;

typedef struct Queue{

     

      Node* front = NULL;

      Node* tail = NULL;

     

}Queue;

程序主体框架:

#include <iostream>

#include <stdio.h>

#include <malloc.h>

#include <string.h>

using namespace std;

typedef struct data{

    int hour;

    int minute;

}time;

typedef struct node{

   

    int id;//进程编号

    char name[20];//进程名

    int good;//优先级

    time arrive;//到达就绪队列的时间

    int zx;//执行时间

    time start;//开始执行时间

    time finish;//执行完成时间

    int zz;//周转时间=执行完成时间-到达就绪队列时间

    float zzxs;//带权周转时间=周转时间/执行时间

    struct node* next;

   

}Node;

typedef struct Queue{

   

    Node* front = NULL;

    Node* tail = NULL;

   

}Queue;

Queue* init(){

   

    Queue* p = (Queue*)malloc(sizeof(Queue));

    p->front = NULL;

    p->tail = NULL;

    return p;

   

}

//函数名:timecompare()          参数:tt 当前时间, p 进程到达时间

bool timecompare(time tt,time p){//tt<p(时间没到) false    tt >= p true

    //函数功能:比较进程到达时间和当前时间,若小于则返回false,否则返回true

   

}

//函数名:timecompare2()          参数:tt 当前时间, p 进程到达时间

bool timecompare2(time tt,time p){//tt<=p(时间没到) false    tt > p true

    //函数功能:比较进程到达时间和当前时间,若小于等于则返回false,否则返回true

   

}

//函数名:Levelcompare()          参数:p,q 进程

bool Levelcompare(Node* p,Node* q){

    //函数功能:比较p,q的优先级,p的优先级高则返回true,低则返回false,否则比较到达时间,p先或同时到达则返回true,反之则false

   

}

//函数名:LevelSorted()          参数:que 进程队列指针

void LevelSorted(Queue* que){

//函数功能:对进程队列按优先级排序

   

}

//函数名:ComputeTime()    参数:tt 当前时间的指针,q 当前进程的指针

time ComputeTime(time* tt,Node* q){

   

//函数功能:更新当前时间和进程的各项时间

          

}

//函数名:priority()    参数:que进程队列指针,tt当前时间 n 进程数

Queue* priority(Queue *que,time tt,int n){

   

//函数功能:进行优先级进程调度,并同时更新当前时间。

   

}

//函数名:Print()    参数:que进程队列指针, n 进程数

void Print(Queue* que,int n){

    //函数功能:打印输出进程优先进程调度结果

   

}

//函数名:ScanIn()    参数:wait进程队列指针, n 进程数

time ScanIn(Queue* wait,int n){

   

    //函数功能:输入进程信息,返回最早的进程到达时间

          

}

int main(){

   

    Queue* wait;

    wait = init();

    int flag,n;

    time earlytime;

   

    while(1){

       printf("请输入操作:(1:开始进程;0:结束进程):");

       scanf("%d",&flag);

       if(flag == 0){

           printf("\n操作结束!\n");

           break;

       }

       else{

           printf("请输入进程数量:");

           scanf("%d",&n);

           earlytime = ScanIn(wait,n);

          

           LevelSorted(wait);

           wait = priority(wait,earlytime,n);

           Print(wait,n);

           wait = init();

          

       }

    }

   

    return 0;

}

    

测试数据

/*

1001 p1 1 9:40 20
1004 p4 4 10:10 10
1005 p5 3 10:05 30
1002 p2 3 9:55 15
1003 p3 2 9:45 25

*/

/*

5001 p1 1 14:40 20
5002 p4 2 10:10 10
5003 p5 3 10:05 30
5004 p2 4 9:55 15
5005 p3 5 9:45 25
5006 p6 6 10:40 20
5007 p8 7 11:10 10 
5008 p9 8 12:05 30
5009 p10 9 13:55 15
5010 p7 10 7:15 15

*/

关键代码

#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;

typedef struct data{
	int hour;
	int minute;
}time;

typedef struct node{
	
	int id;//进程编号 
	char name[20];//进程名 
	int good;//优先级 
	time arrive;//到达就绪队列的时间 
	int zx;//执行时间 
	time start;//开始执行时间 
	time finish;//执行完成时间 
	int zz;//周转时间=执行完成时间-到达就绪队列时间 
	float zzxs;//带权周转时间=周转时间/执行时间 
	struct node* next;
	
}Node;

typedef struct Queue{
	
	Node* front = NULL;
	Node* tail = NULL;
	
}Queue;
void Print(Queue* que,int n);
Queue* init(){
	
	Queue* p = (Queue*)malloc(sizeof(Queue));
	p->front = NULL;
	p->tail = NULL;
	return p;
	
} 
//函数名:timecompare()          参数:tt 当前时间, p 进程到达时间
bool timecompare(time tt,time p){//tt<p(时间没到) false    tt >= p true 
	//函数功能:比较进程到达时间和当前时间,若小于则返回false,否则返回true 
	if((tt.hour<p.hour)||((tt.hour==p.hour)&&(tt.minute<p.minute)))
	return false;
	else
	return true;
}
//函数名:timecompare2()          参数:tt 当前时间, p 进程到达时间
bool timecompare2(time tt,time p){//tt<=p(时间没到) false    tt > p true 
	//函数功能:比较进程到达时间和当前时间,若小于等于则返回false,否则返回true
	if((tt.hour<p.hour)||((tt.hour==p.hour)&&(tt.minute<p.minute||tt.minute==p.minute)))
	return false;
	else
	return true;
}
//函数名:Levelcompare()          参数:p,q 进程
bool Levelcompare(Node* p,Node* q){
	//函数功能:比较p,q的优先级,p的优先级高则返回true,低则返回false,否则比较到达时间,p先或同时到达则返回true,反之则false
	if(p->good>q->good)
	return true;
	else if(p->good<q->good)
	return false;
	else
	{
		if((p->arrive.hour<q->arrive.hour)||(p->arrive.hour==q->arrive.hour&&p->arrive.minute<=q->arrive.minute))
		return true;
		else
		return false;
	}

}
//函数名:LevelSorted()          参数:que 进程队列指针
void LevelSorted(Queue* que){
	
//函数功能:对进程队列按优先级排序	
	Node *bl,*head=NULL,*pre=NULL,*q=NULL,*p,*c;
	bl=que->front;
	while(bl!=NULL)
	{
		Node *p=(Node *)malloc(sizeof(Node));
	 	
	 	*p=*bl;//重点:指针的应用 
		p->next=NULL;
	 	if(head==NULL)
	 	{
	 		head=p;
	 		q=p;
		}
		else
		{
			q=head;
			pre=NULL;
			while(q!=NULL)
			{
				
				if(Levelcompare(p,head))
				{
					p->next=head;
					head=p;
					q=head;
					break;
				}
				else if(!Levelcompare(p,q)&&q->next==NULL)
				{
					q->next=p;
					break;
				}
				else if(Levelcompare(p,q))
				{
					p->next=q;
					pre->next=p;
					break;
				}
				pre=q;
				q=q->next;
				
			}
			
		}
		bl=bl->next;
	}
	que->front=head;
	que->tail=pre;
	
}

//函数名:ComputeTime()    参数:tt 当前时间的指针,q 当前进程的指针
time ComputeTime(time* tt,Node* q){
	
//函数功能:更新当前时间和进程的各项时间
	q->start.hour=tt->hour;
	q->start.minute=tt->minute;
	q->finish.minute=(q->start.minute+q->zx)%60;
	q->finish.hour=q->start.hour+(q->start.minute+q->zx)/60;
	q->zz=q->finish.hour*60+q->finish.minute-q->arrive.hour*60-q->arrive.minute;
	q->zzxs=q->zz*1.0/q->zx;
	tt->hour=q->finish.hour;
	tt->minute=q->finish.minute;
			
}
//函数名:priority()    参数:que进程队列指针,tt当前时间 n 进程数
Queue* priority(Queue *que,time tt,int n){
	
//函数功能:进行优先级进程调度,并同时更新当前时间。
int count=n;
	Node *pre=NULL,*p=NULL,*head=NULL,*q=NULL,*Head;
	Head=que->front;
	p=Head;
	while(1)
	{
		if((p->arrive.hour==tt.hour)&&(p->arrive.minute==tt.minute))
		{
			break;
		}pre=p;
			p=p->next;
	}	
	Node *N=(Node *)malloc(sizeof(Node));
	*N=*p;
	N->next=NULL;
	head=N;
	q=head;
	if(p==Head)
	{
		Head=Head->next;
		free(p);
		count--;
	}
	else
	{
		pre->next=p->next;
		free(p);
		count--;
	}
	ComputeTime(&tt,N);
	while(count)
	{
		p=Head;
		pre=NULL;
		while(p!=NULL)
		{
			if(timecompare2(tt,p->arrive)==true)//提前到达 
			{
				Node *N=(Node *)malloc(sizeof(Node));
				*N=*p;
				N->next=NULL;
				q->next=N;
				q=q->next;
				if(p==Head)
				{
					Head=Head->next;
					free(p);
					count--;
				}
				else
				{
					pre->next=p->next;
					free(p);
					count--;
				}
				ComputeTime(&tt,N);
				break;
			}
			pre=p;
			p=p->next;
		}
		if(p==NULL)//按到达时间先后 
		{
			Node *l,*r;
			l=Head;
			r=Head;
			while(r!=NULL)
			{
				if(timecompare2(l->arrive,r->arrive))
				{
					l=r;
				}
				r=r->next;
			}//找到最小到达时间 
			
		tt.hour=l->arrive.hour;tt.minute=l->arrive.minute;
				Node *N=(Node *)malloc(sizeof(Node));
				*N=*l;
				N->next=NULL;
				q->next=N;
				q=q->next;pre=Head;
				if(l==Head)
				{
					Head=Head->next;
					free(l);
					count--;
				}
				else
				{
					while(pre->next!=l)
					{
						pre=pre->next;
					}
					pre->next=l->next;
					free(l);
					count--;
				}
				ComputeTime(&tt,N);
		}
	}
	
			que->front=head;
			return que;
}
//函数名:Print()    参数:que进程队列指针, n 进程数
void Print(Queue* que,int n){
	//函数功能:打印输出进程优先进程调度结果
	float pz=0,px=0;
	Node *p;
	p=que->front;
	printf("模拟进程优先进程调度过程输出结果\n  id号    名字\t优先级\t到达时间  执行时间(分钟)\t开始时间\t完成时间  周转时间(分钟)  带权周转系数\n"); 
	while(p!=NULL)
	{
		printf("%6d %6s %6d %6d:%02d %10d %17d:%02d %12d:%02d %10d(分钟) %12.2f\n",p->id,p->name,p->good,p->arrive.hour,p->arrive.minute,p->zx,p->start.hour,p->start.minute,p->finish.hour,p->finish.minute,p->zz,p->zzxs);
		pz=pz+p->zz;
		px=px+p->zzxs;
		p=p->next;
	} 
	printf("系统平均周转时间为:\t\t\t\t\t\t\t\t\t%.2f\n",pz/n);
	printf("系统平均带权周转系数为:        \t\t\t\t\t\t\t\t\t\t%.2f\n",px/n);
}
//函数名:ScanIn()    参数:wait进程队列指针, n 进程数
time ScanIn(Queue* wait,int n){
	
	//函数功能:输入进程信息,返回最早的进程到达时间
	int count; 
	count=n;
	time N;
	Node *q;
	q=wait->tail;
	printf("请输入进程的参数:\nid号 名字 优先级 到达时间 执行时间(分钟):\n");
	 while(count--)
	 {
	 	Node *p=(Node *)malloc(sizeof(Node));
	 	p->next=NULL;
	 	scanf("%d %s %d %d:%d %d",&p->id,&p->name,&p->good,&p->arrive.hour,&p->arrive.minute,&p->zx);
	 	if(wait->front==NULL&&wait->tail==NULL)
	 	{
	 		wait->front=p;
	 		q=p;
	 		N.hour=p->arrive.hour;
	 		N.minute=p->arrive.minute;
		}
		else
		{
			q->next=p;
			q=p;
			wait->tail=p;
			if((p->arrive.hour<N.hour)||((p->arrive.hour==N.hour)&&(p->arrive.minute<N.minute)))
			{
				N.hour=p->arrive.hour;
	 			N.minute=p->arrive.minute;
			}
		}
	 }
	 return N;
}

int main(){
	
	Queue* wait;
	wait = init();
	int flag,n;
	time earlytime;
	
	while(1){
		printf("请输入操作:(1:开始进程;0:结束进程):");
		scanf("%d",&flag);
		if(flag == 0){
			printf("\n操作结束!\n");
			break; 
		} 
		else{
			printf("请输入进程数量:");
			scanf("%d",&n);
			earlytime = ScanIn(wait,n);//函数功能:输入进程信息,返回最早的进程到达时间
			LevelSorted(wait);//函数功能:对进程队列按优先级排序
			wait = priority(wait,earlytime,n);//函数功能:进行优先级进程调度,并同时更新当前时间。
			Print(wait,n);//函数功能:打印输出进程优先进程调度结果
			wait = init();
			
		}
	}
	
	return 0;

}

运行结果

实验总结

1、在开始实验之前必须有正确的设计思路

2、理解了优先级的进程调度,当时间和优先级冲突时,首先考虑优先级

3、如果有两个Node *p,q;则p=q和*p=*q的含义是不同的,前者表示两者指向同一个结点,后者表示赋值

4、单链表的创建和应用还不是很熟练,还得多加练习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/424005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring重点记录

文章目录 1.Spring的组成2.Spring优点3.IOC理论推导4.IOC本质5.IOC实现&#xff1a;xml或者注解或者自动装配&#xff08;零配置&#xff09;。6.hellospring6.1beans.xml的结构为&#xff1a;6.2.Spring容器6.3对象的创建和控制反转 7.IOC创建对象方式7.1以有参构造的方式创建…

【硬件相关】RDMA网络类别及基础介绍

文章目录 一、前言1、RDMA网络协议2、TCP/IP网络协议 二、RDMA类别1、IB2、RoCE3、iWARP 三、RDMA对比1、优缺点说明a、性能b、扩展性c、维护难度 2、总结说明 一、前言 roce-vs-infiniband-vs-tcp-ip RoCE、IB和TCP等网络的基本知识及差异对比 分布式存储常见网络协议有TCP/IP…

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…

c语言--qsort函数(详解)

目录 一、定义二、用qsort函数排序整型数据三、用qsort排序结构数据四、qsort函数的模拟实现 一、定义 二、用qsort函数排序整型数据 #include<stdio.h> scanf_S(int *arr,int sz) {for (int i 0; i < sz; i){scanf("%d", &arr[i]);} } int int_cmp(c…

点云数据结构化与体素化理论学习

一、PCD点云数据存储格式的进一步认识 &#xff08;一&#xff09;PCD点云存储格式相较于其它存储格式&#xff08;如PLY、STL、OBJ、X3D等&#xff09;的优势[1] &#xff08;1&#xff09;具有存储和处理有组织的点云数据集的能力&#xff0c;这对于实时应用和增强现实及机器…

GEE入门篇|图像处理(三):阈值处理、掩膜和重新映射图像

阈值处理、掩膜和重新映射图像 本章前一节讨论了如何使用波段运算来操作图像&#xff0c; 这些方法通过组合图像内的波段来创建新的连续值。 本期内容使用逻辑运算符对波段或索引值进行分类&#xff0c;以创建分类图像。 1.实现阈值 实现阈值使用数字&#xff08;阈值&#xf…

YOLOv9独家原创改进|增加SPD-Conv无卷积步长或池化:用于低分辨率图像和小物体的新 CNN 模块

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、文章摘要 卷积神经网络(CNNs)在计算即使觉任务中如图像分类和目标检测等取得了显著的成功。然而&#xff0c;当图像分辨率较低或物体较小时&…

电源通常向计算机内部的各种组件提供的三种电压:1

本文将与您分享电源通常为计算机内部各个组件提供的三种电压是什么。 小编觉得还是比较实用的&#xff0c;所以分享给大家&#xff0c;作为参考。 下面就跟随小编一起来看看吧。 电源通常为电脑内部的各个部件提供三种电压&#xff1a; 1&#xff0e; 5V&#xff0c;主要供给主…

【k8s管理--两种方式安装prometheus】

1、k8s的监控方案 1.1 Heapster Heapster是容器集群监控和性能分忻工具&#xff0c;天然的支持Kubernetes和CoreOS。 Kubernetes有个出名的监控agent–cAdvisor。在每个kubernetes Node上都会运行cAdvisor&#xff0c;它会收集本机以及容器的监控数(cpu,memory,filesystem,ne…

Matlab 机器人工具箱 RobotArm类

文章目录 1 RobotArm1.1 方法1.2 注意2 RobotArm.RobotArm3 RobotArm.cmove4 其他官网:Robotics Toolbox - Peter Corke 1 RobotArm 串联机械臂类 1.1 方法 方法描述plot显示机器人的图形表示teach驱动物理和图形机器人mirror使用机器人作为从机来驱动图形</

C++ 设计模式

文章目录 类图泛化实现关联聚合组合依赖总结 类内部的三种权限&#xff08;公有、保护、私有&#xff09;类的三种继承方式描述与图总结 面向对象七大原则单一职责原则&#xff08;Single Responsibility Principle&#xff09;里氏替换原则&#xff08;Liskov Substitution Pr…

C3_W2_Collaborative_RecSys_Assignment_吴恩达_中英_Pytorch

Practice lab: Collaborative Filtering Recommender Systems(实践实验室:协同过滤推荐系统) In this exercise, you will implement collaborative filtering to build a recommender system for movies. 在本次实验中&#xff0c;你将实现协同过滤来构建一个电影推荐系统。 …

【Memory协议栈】Memory Abstraction Interface模块介绍

目录 前言 正文 1.功能简介 2.关键概念 3.关键类型定义 3.1 MemIf_StatusType 3.2 MemIf_JobResultType 3.3 MemIf_ModeType 4.关键API定义 4.1 MemIf_SetMode 4.2 MemIf_Read 4.3 MemIf_Write 4.4 MemIf_Cancel 4.5 MemIf_GetStatus 4.6 MemIf_GetJobResult 4…

「滚雪球学Java」:集合(章节汇总)

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Ocr之PaddleOcr模型训练

目录 一、系统环境 1 镜像拉取ppocr 进行部署 2 安装paddlepaddle 二、训练前的准备 1 下载源码 2 预模型下载 3 修改模型训练文件yml 4 编排训练集 5 执行脚本进行训练 6 需要修改文件夹名称 三、开始训练 1 执行训练命令 2 对第一次评估进行解释 3 引言 五、总…

【解决方案】ArcGIS Engine二次开发时,运行后出现“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain...”

我们在做ArcGIS Engine二次开发时&#xff0c;特别是新手&#xff0c;安装好了开发环境&#xff0c;满怀信心的准备将按照教程搭建好的框架在Visual Studio中进行运行。点击运行后&#xff0c;却出现了“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化…

2023年09月CCF-GESP编程能力等级认证Scratch图形化编程四级真题解析

一、单选题(共15题,共30分) 第1题 人们所使用的手机上安装的 App 通常指的是( )。 A:一款操作系统 B:一款应用软件 C:一种通话设备 D:以上都不对 答案:B 第2题 下列流程图的输出结果是?( ) A:9 B:7 C:5 D:11 答案:A 第3题 默认小猫角色,执行下列程序…

【Linux】软件管理yum | 编辑器vim | vim插件安装

目录 1. Linux软件管理yum 1.1 什么是软件包 1.2 查看软件包 1.3 如何安装软件 1.4 如何卸载软件 2. Linux编辑器vim 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2.6 插件安装 1. Vim-Plug 3. coc.nvim …

力扣hot100题解(python版44-47题)

44、二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1a;…

C++的内联函数

目录 前言 内联函数 为什么声明和定义分离 为什么声明和定义分离后不出错 为什么内联函数不支持声明和定义分离 为什么内联函数支持声明和定义不分离 坚持声明和定义不分离的解决方法 static修饰函数 inline修饰函数 结论 声明和定义不分离的应用场景 前言 在C语言…