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

实验指南

运行环境:

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;elsereturn true;
}
//函数名:timecompare2()          参数:tt 当前时间, p 进程到达时间
bool timecompare2(time tt,time p){//tt<=p(时间没到) false    tt > p true //函数功能:比较进程到达时间和当前时间,若小于等于则返回false,否则返回trueif((tt.hour<p.hour)||((tt.hour==p.hour)&&(tt.minute<p.minute||tt.minute==p.minute)))return false;elsereturn true;
}
//函数名:Levelcompare()          参数:p,q 进程
bool Levelcompare(Node* p,Node* q){//函数功能:比较p,q的优先级,p的优先级高则返回true,低则返回false,否则比较到达时间,p先或同时到达则返回true,反之则falseif(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;elsereturn 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、单链表的创建和应用还不是很熟练,还得多加练习。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多租户 TransmittableThreadLocal 线程安全问题

在一个多租户项目中&#xff0c;用户登录时,会在自定义请求头拦截器AsyncHandlerInterceptor将该用户的userId,cstNo等用户信息设置到TransmittableThreadLocal中,在后续代码中使用.代码如下: HeaderInterceptor 请求头拦截器 public class HeaderInterceptor implements Asyn…

阿里云国际云服务器全局流量分析功能详细介绍

进行全局流量分析时&#xff0c;内网DNS解析会作为一个整体模块&#xff0c;其他模块的边缘虚框颜色会置灰&#xff0c;示意作为一个整体进行全局分析&#xff0c;左侧Region可以展开/汇总&#xff0c;也可以单独选中某个Region模块进行分析&#xff08;这时其他Region的流量线…

【Java面试题】Redis的用途

以下是一些常见的用途 1.缓存 Redis 可以用作缓存系统&#xff0c;&#xff0c;将频繁访问的数据存储在内存中&#xff0c;从而加快数据访问速度&#xff0c;减少对数据库的访问压力。 2.消息队列 Redis 支持发布/订阅模式和列表数据结构&#xff0c;可以用作消息队列系统的…

道可云元宇宙每日资讯|厦门首个元宇宙办税大厅启用

道可云元宇宙每日简报&#xff08;2024年3月1日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 中国军号元宇宙发布会即将举行 近日&#xff0c;解放军新闻传播中心中国军号即将正式上线。中国军号元宇宙发布会也将在“云端”与您见面。全方位展现解放军新闻传播…

加密与安全_探索签名算法

文章目录 概述应用常用数字签名算法CodeDSA签名ECDSA签名小结 概述 在非对称加密中&#xff0c;使用私钥加密、公钥解密确实是可行的&#xff0c;而且有着特定的应用场景&#xff0c;即数字签名。 数字签名的主要目的是确保消息的完整性、真实性和不可否认性。通过使用私钥加…

云服务器购买教程

在购买云服务器之前&#xff0c;建议仔细评估自身需求和预算&#xff0c;并与多个云服务提供商进行比较&#xff0c;以确保选择到最适合的解决方案。购买云服务器的具体步骤可能因所选云服务提供商而异。以下以实际操作的方式介绍如何购买一款云服务器。 云服务器购买常见问题…

【数仓】zookeeper软件安装及集群配置

相关文章 【数仓】基本概念、知识普及、核心技术【数仓】数据分层概念以及相关逻辑【数仓】Hadoop软件安装及使用&#xff08;集群配置&#xff09;【数仓】Hadoop集群配置常用参数说明 一、环境准备 准备3台虚拟机 Hadoop131&#xff1a;192.168.56.131Hadoop132&#xff…

【Spring连载】使用Spring Data访问 MongoDB----对象映射之基于类型的转换器

【Spring连载】使用Spring Data访问 MongoDB----对象映射之基于类型的转换器 一、自定义转换二、转换器消歧(Disambiguation)三、基于类型的转换器3.1 写转换3.2 读转换3.3 注册转换器 一、自定义转换 下面的Spring Converter实现示例将String对象转换为自定义Email值对象: R…

蓝桥杯_定时器的综合应用实例

一 工程 代码 在单片机训练平台上&#xff0c;利用定时器T0&#xff0c;数码管模块和2个独立按键&#xff08;J5的2&#xff0c;3短接&#xff09;&#xff0c;设计一个秒表&#xff0c;具有清零&#xff0c;暂停&#xff0c;启动功能。 显示模式&#xff1a;分-秒-0.05秒&…

Linux进程——信号详解(上)

文章目录 信号入门生活角度的信号技术应用角度的信号用kill -l命令可以察看系统定义的信号列表信号处理常见方式概述 产生信号通过键盘进行信号的产生&#xff0c;ctrlc向前台发送2号信号通过系统调用异常软件条件 信号入门 生活角度的信号 你在网上买了很多件商品&#xff0…

前端面试练习24.3.2-3.3

HTMLCSS部分 一.说一说HTML的语义化 在我看来&#xff0c;它的语义化其实是为了便于机器来看的&#xff0c;当然&#xff0c;程序员在使用语义化标签时也可以使得代码更加易读&#xff0c;对于用户来说&#xff0c;这样有利于构建良好的网页结构&#xff0c;可以在优化用户体…

vue3项目中如何一个vue组件中的一个div里面的图片铺满整个屏幕样式如何设置

在Vue 3项目中&#xff0c;要使一个div内的图片铺满整个屏幕&#xff0c;你需要确保几个关键点&#xff1a;div元素和图片元素的样式设置正确&#xff0c;以及确保它们能够覆盖整个视口&#xff08;viewport&#xff09;。以下是一个简单的步骤和代码示例&#xff0c;帮助你实现…

代码随想录算法训练营第四八天 | 买股票

目录 只买卖一次可买卖多次 LeetCode 121. 买卖股票的最佳时机 LeetCode 122. 买卖股票的最佳时机II 只买卖一次 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某…

浏览器输入URL到页面渲染经历了哪些过程?

浏览器输入URL到页面渲染的过程可以分为以下几个步骤&#xff1a; 解析URL&#xff1a;当用户在浏览器的地址栏输入URL后&#xff0c;浏览器会首先解析这个URL&#xff0c;判断其是否合法。查找缓存&#xff1a;浏览器会查看自己的缓存&#xff0c;判断是否有之前访问过的这个U…

论文阅读--Diffusion Models for Reinforcement Learning: A Survey

一、论文概述 本文主要内容是关于在强化学习中应用扩散模型的综述。文章首先介绍了强化学习面临的挑战&#xff0c;以及扩散模型如何解决这些挑战。接着介绍了扩散模型的基础知识和在强化学习中的应用方法。然后讨论了扩散模型在强化学习中的不同角色&#xff0c;并对其在多个…

【JavaSE】实用类——String、日期等

目录 String类常用方法String类的equals()方法String中equals()源码展示 “”和equals()有什么区别呢&#xff1f; StringBuffer类常用构造方法常用方法代码示例 面试题&#xff1a;String类、StringBuffer类和StringBuilder类的区别&#xff1f;日期类Date类Calendar类代码示例…

leetcode169. 多数元素的四种解法

leetcode169. 多数元素 题目描述 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 1.哈希 class Solution { public:int majority…

【vue3】命令式组件封装,message封装示例;(函数式组件?)

仅做代码示例&#xff1b;当然改进的地方还是不少的&#xff0c;仅作为该类组件封装方式的初步启发&#xff1b; 理想大成肯定是想要像 饿了么 这些组件库一样。 有的人叫这函数式组件&#xff0c;有的人叫这命令式组件&#xff0c;我个人还是偏向于命令式组件的称呼。因为以vu…

Django配置静态文件

Django配置静态文件 目录 Django配置静态文件静态文件配置调用方法 一般我们将html文件都放在默认templates目录下 静态文件放在static目录下 static目录大致分为 js文件夹css文件夹img文件夹plugins文件夹 在浏览器输入url能够看到对应的静态资源&#xff0c;如果看不到说明…

向爬虫而生---Redis 探究篇4<Redis主从复制(2)>

前言: 继续上一篇向爬虫而生---Redis 探究篇4&#xff1c;Redis主从复制(1)&#xff1e;-CSDN博客 正文: 读写操作和一致性保证 主节点和从节点对读写操作的不同处理方式 在Redis主从复制中&#xff0c;主节点和从节点对读写操作有不同的处理方式&#xff1a; 主节点&…