操作系统进程调度算法模拟__MFC实现
进程调度模拟算法
进程调度模拟算法进程调度是操作系统中的重要组成部分之一,它负责决定在多道程序环境下,哪个进程将获得CPU的使用权。
进程调度模拟算法是为了研究和评估不同调度策略的性能而开发的一种仿真方法。
在实际系统中,调度算法会受到多种因素的影响,如进程优先级、进程的I/O需求、进程的实际执行时间等。
通过模拟这些因素,可以更好地理解不同调度算法之间的差异,并选择最合适的算法来满足特定需求。
下面介绍两种常见的进程调度模拟算法:先来先服务(FCFS)和最短作业优先(SJF)算法。
1. 先来先服务(FCFS)算法:该算法按照进程到达的顺序来调度任务。
当一个进程完成或阻塞时,下一个已到达的进程将获得CPU的使用权。
这种算法非常简单,但是不适用于长作业时间和短作业时间交替出现的情况。
在短作业启动时,长作业仍然在运行,使得短作业的等待时间增加。
2. 最短作业优先(SJF)算法:该算法根据任务的执行时间来调度进程。
在该算法中,每个进程的执行时间都是已知的,并且操作系统根据已知的执行时间来决定哪个进程获得CPU的使用权。
在短作业优先算法中,短作业将会先被调度,这样有助于减少平均周转时间和等待时间。
但是,短作业优先算法容易产生“饥饿”现象,即长作业可能会一直等待,而短作业一直得到CPU的使用权。
除了以上两种算法,还有其他的进程调度模拟算法。
例如:- 时间片轮转(RR)调度算法:使用固定的时间片来调度进程,当时间片用完后,该进程被放入就绪队列的末尾。
- 优先级调度算法:每个进程都拥有一个优先级,优先级越高的进程越早被调度。
这种方法可以根据不同进程的紧迫程度和重要性来进行调度。
- 多级反馈队列调度算法:将就绪队列划分为多个队列,并根据进程的性质和优先级将进程放入不同的队列。
每个队列都有不同的优先级和时间片大小,进程可以通过提高优先级或时间片大小来提高被调度的机会。
在实际应用中,需要根据系统需求和性能指标选择合适的调度算法。
常用的性能指标包括平均周转时间、平均等待时间、CPU利用率等。
操作系统课程设计报告-进程调度的模拟实现
操作系统课程设计报告专业计算机科学与技术学生姓名班级学号指导教师完成日期博雅学院ﻬ题目:进程调度的模拟实现的模拟实现一、设计目的本课程设计是学习完“操作系统原理”课程后进行的一次全面的综合训练,通过课程设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。
在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个。
也就是说能运行的进程数大于处理机个数。
为了使系统中的进程能有条不紊地工作,必须选用某种调度策略,选择一进程占用处理机。
要求学生设计一个模拟处理机调度算法,以巩固和加深处理机调度的概念.二、设计内容1)概述选择一个调度算法,实现处理机调度。
设计要求:1)进程调度算法包括:时间片轮转法,短作业优先算法,动态优先级算法。
2)可选择进程数量3)本程序包括三种算法,用C或C++语言实现,执行时在主界面选择算法(可用函数实现),进入子页面后输入进程数,(运行时间,优先数由随机函数产生),执行,显示结果。
调度时总是选取优先数最大的进程优先运行2.每个进程的优先数,运行时间,由程序任意指定.3.为了调度方便,把进程按给定优先级(动态优先级算法中)从小到大排成一个队列。
按给定运行时间(短作业优先)从小到大排成一个队列用一个变量作为队首指针,指向队列的第一个进程。
4.处理机调度总是选队首进程运行。
由于本实验是模拟处理机调度,所以被选中的进程并不实际的启动运行,而是执行:优先数-1(动态优先级算法中)要求运行时间-1来模拟进程的一次运行。
5.进程运行一次后,若要求运行时间不等于0,则再将它加入队列(动态优先级算法中:按优先数大小插入.),且改变队首指针:若要求运行时间=0,则把它的状态改为完成(C)状态,且退出队列。
(5)对于遇到优先数一致的情况,采用FIFO策略解决.3。
概要设计(1)本程序用两种算法对五个进程进行调度,每个进程可有三个状态,并假设初始状态为就绪状态。
操作系统进程调度实验
操作系统进程调度实验操作系统进程调度是操作系统中非常重要的一个功能,它决定了多个进程的执行顺序和调度策略。
进程调度的好坏直接影响着系统的性能和资源利用率。
本实验旨在通过实现一个简单的进程调度模拟,了解不同的调度算法,探讨其优劣和适用场景。
一、实验目的和原理本实验的目标是实现进程调度模拟,并探究不同调度算法的性能和适用场景。
通过实验,我们可以了解以下内容:1.进程调度算法的基本原理和实现方式;2.比较不同调度算法的优劣和特点;3.了解不同调度算法在不同场景下的应用。
二、实验环境和工具本实验使用C语言进行实现,可以选择任何一种编程环境和工具,例如Dev-C++、Visual Studio等。
三、实验过程及方法1.实现一个进程控制块(PCB)的数据结构,用来保存进程的相关信息,包括进程ID、进程状态、优先级等。
2.实现一个进程队列,用来保存就绪队列中的进程。
可以使用数组或链表等数据结构实现。
3. 实现不同调度算法的函数,包括先来先服务(FCFS)、最短作业优先(SJF)、优先级调度(Priority Scheduling)和时间片轮转(Round Robin)等。
4.根据实际需求生成一批进程,设置其信息,并根据不同算法进行调度。
5.对比不同算法的运行结果和性能,分析其优劣。
四、实验结果和分析通过实验,我们可以得到每个算法的平均等待时间、平均周转时间和吞吐量等性能指标。
根据这些指标,我们可以对不同算法进行评价和分析。
1.先来先服务(FCFS)算法FCFS算法是最简单的调度算法,按照进程到达的顺序进行调度。
它的主要优点是实现简单、公平性好。
然而,FCFS算法有明显的缺点,会导致长作业等待时间过长,产生"饥饿"现象。
2.最短作业优先(SJF)算法SJF算法是按照进程的执行时间长短进行调度的算法。
它能够最大限度地减少平均等待时间和周转时间,但是需要提前知道所有进程的执行时间,这在实际中是很难做到的。
调度算法C语言实现
调度算法C语言实现调度算法是操作系统中的重要内容之一,它决定了进程在系统中的运行方式和顺序。
本文将介绍两种常见的调度算法,先来先服务(FCFS)和最短作业优先(SJF),并用C语言实现它们。
一、先来先服务(FCFS)调度算法先来先服务(FCFS)调度算法是最简单的调度算法之一、它按照进程到达的先后顺序进行调度,即谁先到达就先执行。
实现这个算法的关键是记录进程到达的顺序和每个进程的执行时间。
下面是一个用C语言实现先来先服务调度算法的示例程序:```c#include <stdio.h>//进程控制块结构体typedef structint pid; // 进程IDint arrivalTime; // 到达时间int burstTime; // 执行时间} Process;int maiint n; // 进程数量printf("请输入进程数量:");scanf("%d", &n);//输入每个进程的到达时间和执行时间Process process[n];for (int i = 0; i < n; i++)printf("请输入进程 %d 的到达时间和执行时间:", i);scanf("%d%d", &process[i].arrivalTime,&process[i].burstTime);process[i].pid = i;}//根据到达时间排序进程for (int i = 0; i < n - 1; i++)for (int j = i + 1; j < n; j++)if (process[i].arrivalTime > process[j].arrivalTime) Process temp = process[i];process[i] = process[j];process[j] = temp;}}}//计算平均等待时间和平均周转时间float totalWaitingTime = 0; // 总等待时间float totalTurnaroundTime = 0; // 总周转时间int currentTime = 0; // 当前时间for (int i = 0; i < n; i++)if (currentTime < process[i].arrivalTime)currentTime = process[i].arrivalTime;}totalWaitingTime += currentTime - process[i].arrivalTime;totalTurnaroundTime += (currentTime + process[i].burstTime) - process[i].arrivalTime;currentTime += process[i].burstTime;}//输出结果float avgWaitingTime = totalWaitingTime / n;float avgTurnaroundTime = totalTurnaroundTime / n;printf("平均等待时间:%f\n", avgWaitingTime);printf("平均周转时间:%f\n", avgTurnaroundTime);return 0;```以上程序实现了先来先服务(FCFS)调度算法,首先根据进程的到达时间排序,然后依次执行每个进程,并计算总等待时间和总周转时间。
操作系统---进程调度算法的模拟
void blockQueueUpdate()
///查看阻塞队列中的进程信息
void blockQueueWalk()
⑤模拟动态优先权进程调度函数定义:
///初始化进程PCB数据,返回PCB头指针
PCB * initData()
///模拟CPU执行1个时间片的操作
if(cpuProcess->allTime == 0){ ///若当前执行进程还需CPU时间片为0
cpuProcess->state = Finish; ///设置当前进程状态为终止
free(cpuProcess); ///释放该进程的PCB内存空间
cpuBusy = 0; ///CPU状态设置为空闲
进程每运行一个时间片,优先数减3。
(4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
(5)分析程序运行的结果,谈一下自己的认识。
四、实验结果及分析
(1)实验关键代码
①模拟PCB数据结构定义:
///枚举进程的状态:新建、就绪、执行、阻塞、终止
⑪第11个时间片后:
⑫第12个时间片后:
⑬第13个时间片后:
⑭第14个时间片后:
⑮第15个时间片后:
⑯第16个时间片后:
⑰第17个时间片后:
⑱第18个时间片后:
⑲第19个时间片后:
⑳第20个时间片后:
(3)实验结果分析
①调度算法开始之前进程PCB信息为:
②调度算法结束之后进程PCB信息为:
③调度算法分析:
}///end if
///更新就绪队列和阻塞队列中的进程信息
c语言实现进程调度算法
c语言实现进程调度算法进程调度算法是操作系统中的一个重要组成部分,用于决定在多道程序环境下,选择哪个进程来占用CPU并执行。
C语言是一种通用的编程语言,可以用于实现各种进程调度算法。
这里我将分别介绍三种常见的进程调度算法:先来先服务调度算法(FCFS)、最短作业优先调度算法(SJF)和轮转法调度算法(RR),并给出用C语言实现的示例代码。
首先,我们来看先来先服务调度算法(FCFS)。
此算法根据到达时间的先后顺序,按照先来后到的顺序进行处理。
下面是基于C语言的先来先服务调度算法实现示例代码:```c#include<stdio.h>struct Process};void FCFS(struct Process proc[], int n)for (int i = 1; i < n; i++)}printf("进程号到达时间服务时间完成时间等待时间周转时间\n");for (int i = 0; i < n; i++)}for (int i = 0; i < n; i++)}int maiint n;printf("请输入进程数:");scanf("%d", &n);struct Process proc[n];for (int i = 0; i < n; i++)printf("请输入进程%d的到达时间和服务时间(用空格分隔):", i + 1);}FCFS(proc, n);return 0;```其次,我们来看最短作业优先调度算法(SJF),该算法选择执行时间最短的进程先执行。
下面是基于C语言的最短作业优先调度算法实现示例代码:```c#include<stdio.h>struct Process};void SJF(struct Process proc[], int n)for (int i = 0; i < n; i++)for (int j = 0; j < i; j++)}shortest_job = i;for (int j = i + 1; j < n; j++)shortest_job = j;}}}for (int i = 1; i < n; i++)}printf("进程号到达时间服务时间完成时间等待时间周转时间\n");for (int i = 0; i < n; i++)}for (int i = 0; i < n; i++)}int maiint n;printf("请输入进程数:");scanf("%d", &n);struct Process proc[n];for (int i = 0; i < n; i++)printf("请输入进程%d的到达时间和服务时间(用空格分隔):", i + 1);}SJF(proc, n);return 0;```最后,我们来看轮转法调度算法(RR),该算法分配一个时间片给每个进程,当时间片用完后,将CPU分配给下一个进程。
进程调度模拟程序 操作系统课程设计
算法---进程调度模拟程序问题:进程调度模拟程序设计要求:编写一个进程调度程序,允许多个进程共行的进程调度程序。
进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为输入进程的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止调度算法的流程图如下:算法实现过程:设计实现流程图设计思想说明:用定义结构体来表示进程控制块函数说明:AddProcess(): 来增加进程sort():按优先级和到达时间排序print():打印attemper():调度代码:#include "stdio.h"#include<windows.h>#define Time int#define Max 100typedef struct process{char name[10];//进程名int priority;Time ReachTime;//到达时间Time NeedTime;//需要时间Time UsedTime;//已用时间char state;//状态}PCB;//进程控制块int n;//标示进程的总数PCB pcb[Max];int pTime;//时间片大小void AddProcess(){char ch;do {system("cls");printf(" n 请输入进程名");scanf("%s",pcb[n].name);printf(" 请输入进程的优先级(0-10)");scanf("%d",&pcb[n].priority);printf(" 请输入进程需要的时间");scanf("%d",&pcb[n].NeedTime);pcb[n].ReachTime=n;pcb[n].UsedTime=0;pcb[n].state='W';n++;do{system("cls");printf("还要继续增加进程吗,是(Y),否(N)");ch=getche();} while(ch!='Y'&&ch!='N'&&ch!='y'&&ch!='n');}while (ch=='Y'||ch=='y');}// 排序函数,将最先运行的进程放在最先即pcb[0]{//用冒泡排序int i,j;PCB temp;//先按到达时间排序for (i=0;i<n-1;i++){for (j=n-2;j>=i;j--){if (pcb[j+1].ReachTime<pcb[j].ReachTime){temp=pcb[j];pcb[j]=pcb[j+1];pcb[j+1]=temp;}}}//再按优先级进行排序for (i=0;i<n-1;i++){for (j=n-2;j>=i;j--){if (pcb[j+1].priority>pcb[j].priority){temp=pcb[j];pcb[j]=pcb[j+1];pcb[j+1]=temp;}}}if (pcb[0].state!='F'){pcb[0].state='R';//将优先级最高的状态置为运行}}//打印void print(){int i;//system("cls");sort();printf(" n t进程名t优先级t到达时间t需要时间t已用时间t状态n");for (i=0;i<n;i++)printf("%10s%10d%10d%15d%15d%15cn",pcb[i].name,pcb[i].priority,pcb[i].ReachTime,pcb[i].NeedTime,pcb[i].UsedTime,pcb[i].state);}}//调度void attemper(){system("cls");printf("调度前:n");print();if ((pcb[0].NeedTime-pcb[0].UsedTime)>pTime){pcb[0].UsedTime+=pTime;//已用时间等于时间片pcb[0].priority--;//优先级减一pcb[0].state='W';}else{pcb[0].UsedTime=pcb[0].NeedTime;//已用时间等于需要时间pcb[0].priority=-1000;//优先级置为零pcb[0].state='F';//完成进程,将状态置为完成}printf("调度后: n");print();}char face(){char choose;printf(" n------------------------------------------- n");printf(" t增加进程,请按1 n");printf(" t打印进程,请按2 n");printf(" t进程调度,请按3 n");printf(" t结束进程请,按0 n");printf(" n------------------------------------------- n");printf(" t请选择:");do{choose=getche();} while(choose!='1'&&choose!='2'&&choose!='3'&&choose!='0');return choose;}void main(){char choose;n=0;//初始化进程数为0 printf("设置时间片的大小");scanf("%d",&pTime);system("cls");choose=face();do{if (choose=='1'){AddProcess();print();}if (choose=='2'){system("cls");print();}if (choose=='3'){attemper();}if (choose=='0'){return;}choose=face();} while(1);}。
操作系统进程调度算法模拟实验
操作系统进程调度算法模拟实验进程调度是操作系统中一个重要的功能,它决定了哪些进程能够获得处理器资源以及如何按照一定的策略来分配这些资源。
为了更好地理解进程调度算法的工作原理,我们可以进行一个模拟实验来观察不同算法的表现效果。
实验设想:我们设想有5个进程要运行在一个单核处理器上,每个进程有不同的运行时间和优先级。
进程信息如下:进程A:运行时间10ms,优先级4进程B:运行时间8ms,优先级3进程C:运行时间6ms,优先级2进程D:运行时间4ms,优先级1进程E:运行时间2ms,优先级5实验步骤:1.先来先服务(FCFS)调度算法实验:将上述进程按照先来先服务的原则排序,运行对应的模拟程序,观察每个进程的运行时间、完成时间和等待时间。
2.最短作业优先(SJF)调度算法实验:将上述进程按照运行时间的大小排序,运行对应的模拟程序,观察每个进程的运行时间、完成时间和等待时间。
3.优先级调度算法实验:将上述进程按照优先级的大小排序,运行对应的模拟程序,观察每个进程的运行时间、完成时间和等待时间。
4.时间片轮转(RR)调度算法实验:设置一个时间片大小,将上述进程按照先来先服务的原则排序,运行对应的模拟程序,观察每个进程的运行时间、完成时间和等待时间。
实验结果:通过模拟实验,我们可以得到每个进程的运行时间、完成时间和等待时间。
对于FCFS算法,进程的运行顺序是按照先来先服务的原则,因此进程A首先得到处理器资源并完成运行,其它进程依次按照到达顺序得到资源。
因此,对于进程A、B、C、D、E,它们的完成时间分别是10ms、18ms、24ms、28ms和30ms,等待时间分别是0ms、10ms、18ms、24ms和28ms。
对于SJF算法,进程的运行顺序是按照运行时间的大小,即短作业优先。
因此,进程E首先得到处理器资源并完成运行,其它进程依次按照运行时间的大小得到资源。
对于进程E、D、C、B、A,它们的完成时间分别是2ms、6ms、12ms、20ms和30ms,等待时间分别是0ms、2ms、6ms、12ms和20ms。
操作系统进程调度优先级算法C语言模拟
操作系统进程调度优先级算法C语言模拟```cstruct Processint pid; // 进程IDint priority; // 优先级};```接下来,我们使用一个简单的示例来说明操作系统进程调度优先级算法的模拟实现。
假设有5个进程需要调度执行,它们的初始优先级和运行时间如下:进程ID,优先级,已运行时间--------,--------,------------P1,4,2P2,3,4P3,1,6P4,2,1P5,5,3首先,我们需要将这些进程按照优先级排序,以得到调度队列。
可以使用冒泡排序算法实现,代码如下:```cvoid bubbleSort(struct Process *processes, int n)for (int i = 0; i < n - 1; i++)for (int j = 0; j < n - i - 1; j++)if (processes[j].priority > processes[j + 1].priority)struct Process temp = processes[j];processes[j] = processes[j + 1];processes[j + 1] = temp;}}}``````c#include <stdio.h>void bubbleSort(struct Process *processes, int n);int maistruct Process processes[] = {{1, 4, 2}, {2, 3, 4}, {3, 1, 6}, {4, 2, 1}, {5, 5, 3}};int n = sizeof(processes) / sizeof(struct Process);bubbleSort(processes, n);printf("初始调度队列:\n");printf("进程ID\t优先级\t已运行时间\n");for (int i = 0; i < n; i++)}//模拟进程调度printf("\n开始模拟进程调度...\n");int finished = 0;while (finished < n)struct Process *current_process = &processes[0];printf("执行进程 P%d\n", current_process->pid);finished++;printf("进程 P%d 执行完毕\n", current_process->pid);} else}bubbleSort(processes, n);}printf("\n所有进程执行完毕,调度队列的最终顺序为:\n"); printf("进程ID\t优先级\t已运行时间\n");for (int i = 0; i < n; i++)}return 0;```以上代码中,我们使用了一个变量`finished`来记录已完成的进程数量,当`finished`等于进程数量`n`时,所有进程执行完毕。
操作系统五种进程调度算法的代码
操作系统五种进程调度算法的代码一、先来先服务(FCFS)调度算法先来先服务(FCFS)调度算法是操作系统处理进程调度时比较常用的算法,它的基本思想是按照进程的提交时间的先后顺序依次调度进程,新提交的进程会在当前运行进程之后排队,下面通过C语言代码来实现先来先服务(FCFS)调度算法:#include <stdio.h>#include <stdlib.h>//定义进程的数据结构struct Processint pid; // 进程标识符int at; // 到达时间int bt; // 执行时间};//进程调度函数void fcfs_schedule(struct Process *processes, int n)int i, j;//根据进程的到达时间排序for(i = 0; i < n; i++)for(j = i+1; j < n; j++)if(processes[i].at > processes[j].at) struct Process temp = processes[i]; processes[i] = processes[j];processes[j] = temp;//获取各个进程执行完毕的时间int ct[n];ct[0] = processes[0].at + processes[0].bt; for(i = 1; i < n; i++)if(ct[i-1] > processes[i].at)ct[i] = ct[i-1] + processes[i].bt;elsect[i] = processes[i].at + processes[i].bt; //计算各个进程的周转时间和带权周转时间int tat[n], wt[n], wt_r[n];for(i = 0; i < n; i++)tat[i] = ct[i] - processes[i].at;wt[i] = tat[i] - processes[i].bt;wt_r[i] = wt[i] / processes[i].bt;printf("P%d:\tAT=%d\tBT=%d\tCT=%d\tTAT=%d\tWT=%d\tWT_R=%f\n", processes[i].pid, processes[i].at, processes[i].bt, ct[i], tat[i], wt[i], wt_r[i]);//主函数int mainstruct Process processes[] ={1,0,3},{2,3,5},{3,4,6},{4,5,2},{5,6,4}};fcfs_schedule(processes, 5);return 0;输出:。
进程调度算法模拟程序设计
进程调度算法模拟程序设计引言进程调度算法是操作系统中的重要组成部分,它决定了进程在系统中的执行顺序和分配时间片的策略。
为了更好地理解和研究不同的进程调度算法,我们可以设计一个模拟程序来模拟进程的调度过程。
本文将介绍进程调度算法的基本概念和常见的调度算法,并详细讨论如何设计一个进程调度算法模拟程序。
什么是进程调度算法进程调度算法是操作系统中的一种策略,用于决定在多个进程同时请求执行时,系统按照什么样的顺序来选择并分配CPU资源。
进程调度算法的目标是尽可能地提高系统的吞吐量、响应时间和公平性。
常见的进程调度算法先来先服务(FCFS)先来先服务是最简单的进程调度算法,它按照进程到达的先后顺序进行调度。
当一个进程到达系统后,它会被放入就绪队列中,然后按照先后顺序执行。
这种算法的优点是简单易懂,但是存在”饥饿”问题,即长作业会占用CPU资源,导致其他短作业等待时间过长。
短作业优先(SJF)短作业优先算法是根据进程的执行时间来进行调度的。
当一个进程到达系统后,系统会根据其执行时间将其放入适当的位置,执行时间短的进程优先执行。
这种算法可以最大限度地减少平均等待时间,但是对于长作业来说可能会饥饿。
时间片轮转(RR)时间片轮转算法是一种分时调度算法,它将CPU的执行时间划分为多个时间片,每个进程在一个时间片内执行一定的时间,然后切换到下一个进程。
这种算法可以保证所有进程都有机会执行,并且对于响应时间要求较高的任务比较合适。
多级反馈队列(MFQ)多级反馈队列算法是一种综合了FCFS和RR的调度算法。
系统将进程根据优先级划分为多个队列,每个队列都有不同的时间片大小。
当一个进程到达系统后,它被放入第一个队列中,如果在时间片内没有执行完,则被移到下一个队列中。
这种算法可以根据进程的优先级和执行时间动态调整调度策略,提高系统的响应性能。
进程调度算法模拟程序设计程序结构为了设计一个进程调度算法模拟程序,我们需要考虑以下几个方面的内容:1.进程的数据结构:我们可以使用一个进程控制块(PCB)来表示一个进程,PCB包含了进程的状态、优先级、执行时间等信息。
计算机操作系统实验---进程调度
操作系统实验报告--进程调度计科02-8 王长青05年4月17日计算机操作系统实验——进程调度一.实验目的进程调度是处理机管理的核心内容。
通过本实验可以加深理解有关进程控制块、进程队列的概念,并体会和了解优先数调度算法的具体实施办法。
二.程序功能本程序使用VC++编译调试,用于实现进程优先数调度的模拟。
主要包含三个模块:1、主界面:用于显示进程调度的过程。
2、数据录入模块:用于获取进程的初始值,其中有三种获取方式,手动输入方式、随即生成方式和从文件中读去数据的方式。
当用户在主窗口中点击“开始”菜单项时即可打开数据录入对话框,用户通过这三种方式之一均可完成数据的录入。
3、进程控制模块:主要实现创建新的进程,就绪队列的管理,完成队列的管理,进程的调度。
三.实验原理(1)本程序采用优先数调度算法对进程进行调度,每个进程可有三个状态,即:就绪状态,运行状态,完成状态。
并假设初始状态为就绪状态。
这三种状态的转换情况如右图:(2)为了便于处理,程序中的某进程运行时间以时间片为单位计算。
各进程的优先数以及进程需运行的时间片数的初始值均由用户给定(通过数据录入模块完成)。
(3)程序通过设置一个定时器来实现时间片的轮转,时间片的大小是1秒,在定时器消息的响应函数中从用户录入的数据中读取一个创建进程,将其加入到就绪队列中,然后进行调度和执行。
在调度函数中,对于遇到优先数一致的情况,采用FIFO策略解决。
(4)在优先数算法中,进程每执行一次,优先数减3,进程还需要运行的时间数减1。
四.详细设计(1)设计进程控制块PCB结构:struct PCB{ int pid; //进程号int pri; //进程优先数int time; //进程所需运行时间int status; // 进程状态 0就绪,1 执行,-1完成};(2)将进程的各种操作封装在类CProMoni中,该类的定义如下:class CProMoni{public:CProMoni();virtual ~CProMoni();void InsertRQ(PCB* p); //将p所指的进程插入到就绪队列中void InsertFQ(PCB* p); //将p所指的进程插入到完成队列中void ProSchedule(); //进程调度函数void ProRun(); //运行函数void Display(CDC* pDC); //以表格形式输出运行过程bool GetFinishFlag();bool OpenLogFile(); //打开日志文件void CloseLogFile(); //关闭日志文件bool WriteLogToFile(); //向日志文件中写入数据private:PCB *m_pRunning; //指向当前运行的进程CPtrList m_readyList; //就绪队列CPtrList m_finishList; //完成队列bool m_finish; //完成标志CString m_LogFileName; //日志文件名CStdioFile m_LogFile; //日志文件public:int m_clock; //时钟序列};(3)主要成员函数的实现:void CProMoni::InsertRQ(PCB* p){ //将p插入到就绪队列中POSITION pre,pos=m_readyList.GetHeadPosition();PCB *q;while(pos!=NULL){pre=pos;q=(PCB*)m_readyList.GetNext(pos);if(q->pri < p->pri){m_readyList.InsertBefore(pre,p);return;}}if(pos==NULL){m_readyList.AddTail(p);}}void CProMoni::ProSchedule(){//进程调度PCB *p;if(m_pRunning==NULL){if(m_readyList.IsEmpty()){m_finish=true;return;}else{p=(PCB*)m_readyList.RemoveHead();m_pRunning=p;}}else{if(!m_readyList.IsEmpty()){p=(PCB*)m_readyList.GetHead();//m_readyList将头节点与当前PCB的权值比较if(p->pri > m_pRunning->pri ){PCB *q=m_pRunning;m_pRunning=(PCB*)m_readyList.RemoveHead();m_pRunning->status=1;q->status=0;InsertRQ(q);}}}}void CProMoni::ProRun(){//运行进程if(!m_finish){if(m_pRunning==NULL){ AfxMessageBox("当前运行的进程不存在!");return;}m_pRunning->pri-=3;m_pRunning->time-=1;{ m_pRunning->time=0;PCB*p=m_pRunning;p->status=-1;InsertFQ(p);m_pRunning=NULL;}}}(4)试图类的主要成员函数:PCB* CProcessView::CreatePCB(){//创建PCBPCB* p=new PCB;p->pid=n+1;p->pri=m_pris[n];p->time=m_times[n];p->status=0;n++;return p;}#include"pritimedlg.h"void CProcessView::OnStart(){ CPriTimeDlg dlg; //定义数据录入对话框dlg.DoModal();if(dlg.m_ok){ m_proTotal=dlg.m_proNum;for(int i=0;i<m_proTotal;i++){ m_pris[i]=dlg.m_pris[i];m_times[i]=dlg.m_times[i];}m_proMoni.OpenLogFile(); //打开日志文件PCB* p=CreatePCB(); //创建新进程m_proMoni.InsertRQ(p); //将新进程插入到就绪队列中m_proMoni.WriteLogToFile(); //写日志文件m_proMoni.ProSchedule(); //进程调度m_start=true; //设置开始标志Invalidate(); //刷新视图m_killTimer=false;SetTimer(1,1000,NULL);//设置定时器}}void CProcessView::OnTimer(UINT nIDEvent){ m_proMoni.m_clock++;m_proMoni.WriteLogToFile();//写日志m_proMoni.ProRun(); //运行进程if(n<m_proTotal){ PCB *p=CreatePCB();//创建新进程m_proMoni.InsertRQ(p);}m_proMoni.ProSchedule();Invalidate();if(m_proMoni.GetFinishFlag()){//若已完成则删除定时器KillTimer(1);m_killTimer=true;AfxMessageBox("演示完毕");}CScrollView::OnTimer(nIDEvent);}五.运行结果(1)数据录入界面:(2)进程调度过程的结果:六、实验总结通过本实验使我对进程的相关概念及进程的优先数调度算法有了更深的理解,使自己在程序设计及编制方面也有了一定的提高。
计算机操作系统的进程调度算法
计算机操作系统的进程调度算法计算机操作系统是指控制和管理计算机硬件与软件资源的系统软件。
在操作系统中,进程调度算法起着至关重要的作用,它决定了系统中各个进程的执行顺序,合理的调度算法可以提高系统的性能和效率。
本文将对常见的进程调度算法进行介绍和分析。
一、先来先服务调度算法(First-Come, First-Served,FCFS)先来先服务调度算法是最简单的调度算法之一。
按照进程到达的先后顺序依次执行,即抢占后只有等待其他进程执行完毕才能执行。
该算法的优点是简单易实现,但缺点是平均等待时间较长,无法满足实时性要求,容易产生“饥饿”现象。
二、短作业优先调度算法(Shortest Job First,SJF)短作业优先调度算法是通过预测进程执行时间的长短来进行调度的。
当有多个进程同时到达时,选择执行时间最短的进程先执行。
该算法的优点是能够最大限度地减少平均等待时间,但缺点是无法应对长作业的到来,可能导致长作业的等待时间过长。
三、优先级调度算法(Priority Scheduling)优先级调度算法根据进程的优先级来进行调度,优先级高的进程先执行。
该算法可以根据实际需要为不同的进程设置不同的优先级。
该算法的优点是能够满足实时性要求,但缺点是可能导致优先级低的进程长时间等待,产生“饥饿”现象。
四、轮转调度算法(Round Robin,RR)轮转调度算法是一种按照时间片轮流分配CPU的调度算法。
每个进程被分配一个固定的时间片,当时间片用完时,进程被剥夺CPU,并放入就绪队列的末尾等待下一次调度。
该算法的优点是能够公平地分配CPU时间,避免长作业的等待时间过长,缺点是可能导致平均等待时间较长,无法满足实时性要求。
五、多级反馈队列调度算法(Multilevel Feedback Queue,MLFQ)多级反馈队列调度算法是一种综合利用多个调度算法的调度策略。
它将进程划分为多个队列,每个队列采用不同的调度算法。
操作系统综合性实验报告~进程调度(含代码)
XXXXXX计算机系综合性实验实验报告课程名称操作系统B实验学期XXXX 至XXXX 学年第X 学期学生所在系部计算机系年级XXXX 专业班级XXXXXX学生姓名XXXX 学号XXXXXXXXXXXX任课教师XXX实验成绩计算机系制《操作系统B 》课程综合性实验报告开课实验室:年月日附代码:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct node{char name[10]; //进程的名字int round; //一次分配CPU的时间片int cputime; //CPU已执行时间int needtime; //进程执行所需要的时间char state; //进程的状态,W-就绪态,R-执行态,F-完成态int count; //记录进程执行的次数struct node *next; //队列指针}PCB;PCB *ready=NULL,*run=NULL,*finish=NULL; //定义三个队列,就绪队列,执行队列和完成队列int num;void GetFirst(); //从就绪队列取得第一个节点void Output(); //输出各队列信息void InsertTime(PCB *in); //插入就绪片队列void InsertFinish(PCB *in); //插入完成队列void TimeCreate(); //时间片输入函数void RoundRun(); //时间片轮转调度void main(){printf("\n****** 欢迎光临指导******\n");printf("\n****** 时间片轮转进程调度算法******\n");printf("\n****** 计科B082 韩友******\n");printf("\n****** 200807014225 ******\n");printf("\n****** 2011年5月15日******\n");printf("\n请输入要创建的进程数目:\n");scanf("%d",&num);getchar(); //吸收回车符号TimeCreate();RoundRun();Output();}void GetFirst() //取得第一个就绪队列节点{run = ready;if(ready!=NULL){run ->state = 'R';ready = ready ->next;run ->next = NULL;}}void Output() //输出队列信息{PCB *p;p = ready;printf("进程轮数cpu时间需要时间进程状态计数器\n");while(p!=NULL){printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtime,p->state,p->count);p = p->next;}p = finish;while(p!=NULL){printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtime,p->state,p->count);p = p->next;}p = run;while(p!=NULL){printf("%s\t%d\t%d\t%d\t%c\t%d\n",p->name,p->round,p->cputime,p->needtime,p->state,p->count);p = p->next;}}void InsertTime(PCB *in) //将进程插入到就绪队列尾部{PCB *fst;fst = ready;if(ready == NULL){in->next = ready;ready = in;}{while(fst->next != NULL){fst = fst->next;}in ->next = fst ->next;fst ->next = in;}}void InsertFinish(PCB *in) //将进程插入到完成队列尾部{PCB *fst;fst = finish;if(finish == NULL){in->next = finish;finish = in;}else{while(fst->next != NULL)fst = fst->next;}in ->next = fst ->next;fst ->next = in;}}void TimeCreate() //时间片轮转输入函数{PCB *tmp;int i;printf("输入进程名字和进程时间片所需时间:\n");for(i = 0;i < num; i++){if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL){perror("malloc");exit(1);}scanf("%s",tmp->name);getchar();scanf("%d",&(tmp->needtime));tmp ->cputime = 0;tmp ->state ='W';tmp ->round = 2; //假设每个进程所分配的时间片是2tmp ->count = 0;InsertTime(tmp);}}void RoundRun() //时间片轮转调度算法{int flag = 1;GetFirst();while(run != NULL){Output();while(flag){run->count++;run->cputime++;run->needtime--;if(run->needtime == 0) //进程执行完毕{run ->state = 'F';InsertFinish(run);flag = 0;}else if(run->count == run->round)//时间片用完{run->state = 'W';run->count = 0; //计数器清零,为下次做准备InsertTime(run);flag = 0;}}flag = 1;GetFirst();}}。
操作系统实验进程调度
实验三进程调度一. 实验目的加深理解并模拟实现进程(作业)调度算法。
1)熟悉常用的进程调度算法, 如FCFS、SPF、FPF、高响应比优先、时间片轮转;2)结合所学的数据结构及编程知识, 选择三种进程调度算法予以实现。
二. 实验属性该实验为设计性实验。
三. 实验仪器设备及器材普通PC386以上微机四. 实验要求本实验要求2学时完成。
1)本实验要求完成如下任务:2)编程实现单处理机系统中的进程调度, 要求从FCFS、SPF、FPF、高响应比优先、时间片轮转算法中至少选择三个;3)最后编写主函数对所做工作进行测试。
实验前应复习实验中所涉及的理论知识和算法, 针对实验要求完成基本代码编写并完成预习报告、实验中认真调试所编代码并进行必要的测试、记录并分析实验结果。
实验后认真书写符合规范格式的实验报告(参见附录A), 并要求用正规的实验报告纸和封面装订整齐, 按时上交。
五: 实验具体设计此程序模拟了两种调度算法, FCFS和SPF, 首先FCFS就是按照进程的创建顺序依次顺序进行, 流程图为:进程顺序执行SPF:每次都进行循环, 选出在该时间刻运行时间最短的进程优先执行。
1.程序代码具体详解:2.创建一结构体作为进程控制器typedef struct PCB{int ID;char state;int arrivetime;int starttime;int finishtime;int servicetime;struct PCB *next;}pcb;定义全局变量作为计时器int time;//计时器创建进程链表:从txt文件中读取数据, 构造一条不含头结点的单链表void Create_process(){ifstream inFile;inFile.open("test.txt");inFile>>n;inFile.get();int i=0;for (;i<n;i++){p=(pcb *)malloc(sizeof(pcb));inFile>>p->ID;inFile>>p->arrivetime;inFile>>p->servicetime;p->starttime=0;p->finishtime=0;p->state='F';p->next=NULL;if(head==NULL){head=p;q=p;time=p->arrivetime;}if(p->arrivetime < time)time=p->arrivetime;q->next=p;q=p;}若执行FCFS算法, 按顺序遍历链表void fcfs1(){int i;p=head;for(i=0;i<n;i++){if(p->state=='F')q=p;run_fcfs1(q);}p=p->next;}}void run_fcfs1(pcb *p1){time = p1->arrivetime > time? p1->arrivetime:time;p1->starttime=time;printf("\n现在时间: %d,开始运行作业%d\n",time,p1->ID);time+=p1->servicetime;p1->state='T';p1->finishtime=time;printf("ID号到达时间开始运行时间服务时间完成时间\n");printf("%d%10d%12d%12d%12d\n",p1->ID,p1->arrivetime,p1->starttime,p1->servicetime,p 1->finishtime);}若执行SPF算法, 每次都从链表头开始遍历链表, 找出arrivetime<=time并且运行时间最短的节点, 执行该节点进程, 最后再删除该节点。
操作系统五种进程调度算法的代码
进程调度算法的模拟实现⏹实验目的1.本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
2.利用程序设计语言编写算法,模拟实现先到先服务算法FCFS、轮转调度算法RR、最短作业优先算法SJF、优先级调度算法PRIOR、最短剩余时间优先算法SRTF。
3.进行算法评价,计算平均等待时间和平均周转时间。
⏹实验内容及结果1.先来先服务算法2.轮转调度算法3. 优先级调度算法4. 最短时间优先算法5. 最短剩余时间优先算法⏹实验总结在此次模拟过程中,将SRTF单独拿了出来用指针表示,而其余均用数组表示。
⏹完整代码【Srtf.cpp代码如下:】//最短剩余时间优先算法的实现#include<stdio.h>#include<stdlib.h>#include<time.h>typedefstruct{int remain_time;//进程剩余执行时间int arrive_time;//进程到达时间int Tp;//进入就绪队列的时间int Tc;//进入执行队列的时间int To;//进程执行结束的时间int number;//进程编号}Process_Block;//定义进程模块typedefstruct _Queue{Process_Block PB;struct _Queue *next;}_Block,*Process;//定义一个进程模块队列中结点typedefstruct{Process head;//队列头指针Process end;//队列尾指针}Process_Queue;//进程队列Process_Queue PQ;//定义一个全局队列变量int t;//全局时间Process Run_Now;//当前正在运行的进程,作为全局变量void InitQueue(Process_Queue PQ){PQ.head ->next = NULL;PQ.end ->next = PQ.head;}/*初始化队列*/int IsEmpty(Process_Queue PQ){if(PQ.end->next == PQ.head)return 1;//队列空的条件为头指针指向尾指针并且尾指针指向头指针elsereturn 0;}/*判定队列是否为空队列*/void EnQueue(Process_Queue PQ,Process P){Process temp =(Process)malloc(sizeof(_Block));temp = PQ.end;temp->next->next = P;PQ.end->next = P;}/*插入队列操作*/Process DeQueue(Process_Queue PQ){if(IsEmpty(PQ))return NULL;Process temp = PQ.head->next;PQ.head->next= temp ->next;if(PQ.end->next == temp)PQ.end->next = PQ.head;return temp;}/*出列操作*/Process ShortestProcess(Process_Queue PQ){if(IsEmpty(PQ))//如果队列为空,返回{if(!Run_Now)return NULL;elsereturn Run_Now;}Process temp,shortest,prev;int min_time;if(Run_Now)//如果当前有进程正在执行,{shortest = Run_Now;//那么最短进程初始化为当前正在执行的进程,min_time = Run_Now->PB.remain_time;}else//如果当前没有进程执行,{shortest = PQ.head->next;//则最短进程初始化为队列中第一个进程min_time = PQ.head->next->PB.remain_time;}temp = PQ.head;prev = temp;while(temp->next){if(temp->next->PB.remain_time <min_time)//如果当前进程的剩余时间比min_time短,{shortest = temp->next;//则保存当前进程,min_time = shortest->PB.remain_time;prev=temp;//及其前驱}temp=temp->next;}if(shortest == PQ.end->next)//如果最短剩余时间进程是队列中最后一个进程,PQ.end->next = prev;//则需要修改尾指针指向其前驱prev->next = shortest->next;//修改指针将最短剩余时间进程插入到队头return shortest;}/*调度最短剩余时间的进程至队头*/void Run(){Run_Now->PB.remain_time--;//某一时间运行它的剩余时间减return;}/*运行函数*/void Wait(){return ;}int sum(intarray[],int n){int i,sum=0;for(i=0;i<n;i++)sum+=array[i];return sum;}int main(){PQ.head = (Process)malloc(sizeof(_Block));PQ.end = (Process)malloc(sizeof(_Block));Run_Now = (Process)malloc(sizeof(_Block));Run_Now =NULL;InitQueue(PQ);int i,N,Total_Time=0;//Total_Time为所有进程的执行时间之和printf("请输入计算机中的进程数目:\n");scanf("%d",&N);Process *P,temp;P = (Process*)malloc(N*sizeof(Process));int *wt,*circle_t;wt =(int*)malloc(N*sizeof(int));circle_t =(int*)malloc(N*sizeof(int));for(i=0;i<N;i++){P[i] = (Process)malloc(sizeof(_Block));P[i]->PB.number =i+1;P[i]->next =NULL;wt[i] =0;circle_t[i] =0;printf("输入第%d个进程的到达时间及剩余执行时间:\n",i+1);scanf("%d %d",&P[i]->PB.arrive_time,&P[i]->PB.remain_time);}for(i=0;i<N;i++)Total_Time+=P[i]->PB.remain_time;printf("\n进程按顺序运行依次为:\n");i=0;int k=0;for(t=0;;t++){if(Run_Now)//如果当前有进程正在执行{Run();if(t == P[i]->PB.arrive_time)//如果当前时间正好有进程进入{if(P[i]->PB.remain_time < Run_Now->PB.remain_time){temp = P[i];P[i] = Run_Now;Run_Now = temp;//则调度它至运行队列中,Run_Now->PB.Tp=t;Run_Now->PB.Tc=t;wt[Run_Now->PB.number-1]+=Run_Now->PB.Tc-Run_Now->PB.Tp;printf("%d ",Run_Now->PB.number);}EnQueue(PQ,P[i]);//并将当前运行进程重新插入队列中P[i]->PB.Tp=t;k++;i=(i+1)>(N-1)?(N-1):(i+1);}if(Run_Now->PB.remain_time == 0)//如果当前进程运行结束,{Run_Now->PB.To=t;//进程运行结束的时间circle_t[Run_Now->PB.number-1] +=t-Run_Now->PB.arrive_time;free(Run_Now);//则将它所占资源释放掉,Run_Now =NULL;//并修改Run_Now为NULLRun_Now = ShortestProcess(PQ);//从就绪队列中调出最短剩余时间进程至队头,if(!Run_Now)//如果队列为空,转为等待状态{if(IsEmpty(PQ) && k >= N) break;Wait();continue;}else{Run_Now->PB.Tc=t;wt[Run_Now->PB.number-1]+=Run_Now->PB.Tc-Run_Now->PB.Tp;printf("%d ",Run_Now->PB.number);}}}else//如果当前运行进程为空,那么{if(t == P[i]->PB.arrive_time)//如果正好这时有进程入队{k++;EnQueue(PQ,P[i]);Run_Now = DeQueue(PQ);//则直接被调入运行队列中Run_Now->PB.Tp=t;Run_Now->PB.Tc=t;printf("%d ",Run_Now->PB.number);i=(i+1)>(N-1)?(N-1):(i+1);}else{Wait();continue;}}}printf("\n");printf("平均等待时间是:\n%f\n",((float)sum(wt,N))/N);printf("平均周转时间是:\n%f\n",((float)sum(circle_t,N))/N);return 0;}//////////////////////////////////////////////////////【Process.cpp代码如下:】#include<iostream>#include<string>usingnamespace std;class Process{public:string ProcessName; // 进程名字int Time; // 进程需要时间int leval; // 进程优先级int LeftTime; // 进程运行一段时间后还需要的时间};void Copy ( Process proc1, Process proc2); // 把proc2赋值给proc1void Sort( Process pr[], int size) ; // 此排序后按优先级从大到小排列void sort1(Process pr[], int size) ; // 此排序后按需要的cpu时间从小到大排列void Fcfs( Process pr[], int num, int Timepice); // 先来先服务算法void TimeTurn( Process process[], int num, int Timepice); // 时间片轮转算法void Priority( Process process[], int num, int Timepice); // 优先级算法void main(){int a;cout<<endl;cout<<" 选择调度算法:"<<endl;cout<<" 1: FCFS 2: 时间片轮换3: 优先级调度4: 最短作业优先5: 最短剩余时间优先"<<endl; cin>>a;constint Size =30;Process process[Size] ;int num;int TimePice;cout<<" 输入进程个数:"<<endl;cin>>num;cout<<" 输入此进程时间片大小: "<<endl;cin>>TimePice;for( int i=0; i< num; i++){string name;int CpuTime;int Leval;cout<<" 输入第"<< i+1<<" 个进程的名字、cpu时间和优先级:"<<endl;cin>>name;cin>> CpuTime>>Leval;process[i].ProcessName =name;process[i].Time =CpuTime;process[i].leval =Leval;cout<<endl;}for ( int k=0;k<num;k++)process[k].LeftTime=process[k].Time ;//对进程剩余时间初始化cout<<" ( 说明: 在本程序所列进程信息中,优先级一项是指进程运行后的优先级!! )";cout<<endl; cout<<endl;cout<<"进程名字"<<"共需占用CPU时间"<<" 还需要占用时间"<<" 优先级"<<" 状态"<<endl; if(a==1)Fcfs(process,num,TimePice);elseif(a==2)TimeTurn( process, num, TimePice);elseif(a==3){Sort( process, num);Priority( process , num, TimePice);}else// 最短作业算法,先按时间从小到大排序,再调用Fcfs算法即可{sort1(process,num);Fcfs(process,num,TimePice);}}void Copy ( Process proc1, Process proc2){proc1.leval =proc2.leval ;proc1.ProcessName =proc2.ProcessName ;proc1.Time =proc2.Time ;}void Sort( Process pr[], int size) //以进程优先级高低排序{// 直接插入排序for( int i=1;i<size;i++){Process temp;temp = pr[i];int j=i;while(j>0 && temp.leval<pr[j-1].leval){pr[j] = pr[j-1];j--;}pr[j] = temp;} // 直接插入排序后进程按优先级从小到大排列for( int d=size-1;d>size/2;d--){Process temp;temp=pr [d];pr [d] = pr [size-d-1];pr [size-d-1]=temp;} // 此排序后按优先级从大到小排列}/*最短作业优先算法的实现*/void sort1 ( Process pr[], int size) // 以进程时间从低到高排序{// 直接插入排序for( int i=1;i<size;i++){Process temp;temp = pr[i];int j=i;while(j>0 && temp.Time < pr[j-1].Time ){pr[j] = pr[j-1];j--;}pr[j] = temp;}}/*先来先服务算法的实现*/void Fcfs( Process process[], int num, int Timepice){ // process[] 是输入的进程,num是进程的数目,Timepice是时间片大小while(true){if(num==0){cout<<" 所有进程都已经执行完毕!"<<endl;exit(1);}if(process[0].LeftTime==0){cout<<" 进程"<<process[0].ProcessName<< " 已经执行完毕!"<<endl;for (int i=0;i<num;i++)process[i]=process[i+1];num--;}elseif(process[num-1].LeftTime==0){cout<<" 进程"<<process[num-1].ProcessName<< " 已经执行完毕!"<<endl;num--;}else{cout<<endl; //输出正在运行的进程process[0].LeftTime=process[0].LeftTime- Timepice;process[0].leval =process[0].leval-1;cout<<" "<<process[0].ProcessName <<" "<<process[0].Time <<"";cout<<process[0].LeftTime <<" "<<process[0].leval<<" 运行";cout<<endl;for(int s=1;s<num;s++){cout<<" "<<process[s].ProcessName <<" "<<process[s].Time <<"";cout<<process[s].LeftTime <<" "<<process[s].leval<<" 等待"<<endl; ;}} // elsecout<<endl;system(" pause");cout<<endl;} // while}/*时间片轮转调度算法实现*/void TimeTurn( Process process[], int num, int Timepice){while(true){if(num==0){cout<<" 所有进程都已经执行完毕!"<<endl;exit(1);}if(process[0].LeftTime==0){cout<<" 进程"<<process[0].ProcessName<< " 已经执行完毕!"<<endl;for (int i=0;i<num;i++)process[i]=process[i+1];num--;}if( process[num-1].LeftTime ==0 ){cout<<" 进程" << process[num-1].ProcessName <<" 已经执行完毕! "<<endl;num--;}elseif(process[0].LeftTime > 0){cout<<endl; //输出正在运行的进程process[0].LeftTime=process[0].LeftTime- Timepice;process[0].leval =process[0].leval-1;cout<<" "<<process[0].ProcessName <<" "<<process[0].Time <<"";cout<<process[0].LeftTime <<" "<<process[0].leval<<" 运行";cout<<endl;for(int s=1;s<num;s++){cout<<" "<<process[s].ProcessName <<" "<<process[s].Time <<"";cout<<process[s].LeftTime <<" "<<process[s].leval;if(s==1)cout<<" 就绪"<<endl;elsecout<<" 等待"<<endl;}Process temp;temp = process[0];for( int j=0;j<num;j++)process[j] = process[j+1];process[num-1] = temp;} // elsecout<<endl;system(" pause");cout<<endl;} // while}/*优先级调度算法的实现*/void Priority( Process process[], int num, int Timepice){while( true){if(num==0){cout<< "所有进程都已经执行完毕!"<<endl;exit(1);}if(process[0].LeftTime==0){cout<<" 进程" << process[0].ProcessName <<" 已经执行完毕! "<<endl;for( int m=0;m<num;m++)process[m] = process[m+1]; //一个进程执行完毕后从数组中删除num--; // 此时进程数目减少一个}if( num!=1 && process[num-1].LeftTime ==0 ){cout<<" 进程" << process[num-1].ProcessName <<" 已经执行完毕! "<<endl;num--;}if(process[0].LeftTime > 0){cout<<endl; //输出正在运行的进程process[0].LeftTime=process[0].LeftTime- Timepice;process[0].leval =process[0].leval-1;cout<<" "<<process[0].ProcessName <<" "<<process[0].Time <<"";cout<<process[0].LeftTime <<" "<<process[0].leval<<" 运行";cout<<endl; // 输出其他进程for(int s=1;s<num;s++){cout<<" "<<process[s].ProcessName <<" "<<process[s].Time <<" ";cout<<process[s].LeftTime <<" "<<process[s].leval ; if(s==1)cout<<" 就绪"<<endl;elsecout<<" 等待"<<endl;}} // elseSort(process, num);cout<<endl;system(" pause");cout<<endl;} // while}。
操作系统中的进程调度算法
操作系统中的进程调度算法随着现代计算机技术的不断发展,操作系统成为管理计算机系统的核心组件。
操作系统不仅可以控制计算机硬件和软件资源的分配,还可以提高计算机的效率和管理性能。
而进程调度就是操作系统中最重要的功能之一,其目的是实现多个进程之间的均衡,响应用户请求,最大程度的利用计算机资源。
进程调度算法是指操作系统中用来决定哪个进程可以被执行和运行多长时间的算法。
不同的操作系统有不同的进程调度算法,通常根据不同策略来选择进程。
下面将介绍几种经典的进程调度算法。
1. 先来先服务(FCFS)算法FCFS算法是最简单的进程调度算法之一。
它的核心思想是按照进程到达的顺序排队,当一个进程结束执行后,下一个进程将会自动成为就绪队列中的第一个进程。
这种算法的优点在于简单易实现,但是很容易出现长作业长等待的问题,也就是说长时间在等待队列中的进程可能会影响到系统效率。
2. 最短作业优先(SJF)算法SJF算法通过对进程执行时间的估计来决定下一个要执行的进程。
也就是说,当一个新进程加入系统时,选择预计需要最短执行时间的进程进行调度。
这种算法在情况比较稳定时,可以保证平均等待时间最少。
但是当有大量的短作业成批到达时,长作业就可能会一直等待。
3. 优先级算法优先级算法是按照每个进程的优先级确定执行顺序的算法。
通常情况下,优先级由进程的重要性、紧急程度等因素来决定。
优先级越高的进程会先得到执行机会。
这种算法可以保证重要的进程得到优先执行,但是它也存在一个问题:优先级调度可能会导致低优先级的进程一直等待执行,这就是由于饥饿现象的出现。
4. 时间片轮转算法时间片轮转算法是一种按照时间分配资源的算法。
每个进程都被分配一个时间片,在该时间片结束时,操作系统会强制暂停进程的执行,将CPU时间分配给下一个进程执行。
这种算法可以保证每个进程都有机会得到尽可能的执行时间,而且能够避免长时间的等待。
5. 高响应比优先(HRRN)算法HRRN算法是一种综合了SJF和优先级算法的综合调度算法。
操作系统进程调度模拟算法附源码
先来先服务(FCFS)
定义:按照进程到 达的先后顺序进行 调度
优点:实现简单, 适用于CPU繁忙型 进程
缺点:等待时间较 长,可能导致饥饿 现象
适用场景:适用于 CPU密集型进程, 不适用于I/O密集 型进程
最短作业优先(SJF)
定义:按照作业的估计运行时间进行排序,选择最短作业优先执行 优点:响应时间快,作业平均等待时间少 缺点:存在饥饿现象,长作业可能长时间得不到执行 适用场景:适用于作业量较大且作业到达时间间隔较长的情况
Part Five
模拟实验结果及分 析
实验环境及参数设置
处理器:Intel Core i78700K
操作系统:Linux
内存:16GB DDR4 硬盘:256GB SSD
实验结果展示
实验数据:模拟算法在不同情况下的运行结果 数据分析:对实验数据进行分析,得出结论 结果对比:将模拟算法与实际操作系统进行对比,分析差异 结果展示:以图表、表格等形式展示实验结果
优先级调度算法
定义:根据进 程的优先级进 行调度,优先 级高的进程优 先获得处理器
资源
分类:静态优 先级调度算法 和动态优先级
调度算法
静态优先级调 度算法:优先 级在进程创建 时就确定,且 在运行过程中
保持不变
动态优先级调 度算法:优先 级根据进程的 行为和需求动
态调整
轮转法(RR)
定义:轮转法是 一种简单且常用 的进程调度算法, 也称为循环调度
算法。
原理:按照进程 到达的先后顺序, 按照固定的时间 片进行循环调度。
特点:每个进程 分配一个固定时 间片,时间片用 完后自动切换到 下一个进程,如 果时间片未用完, 则一直运行直到
c语言编写的进程调度算法
c语言编写的进程调度算法C语言编写的进程调度算法进程调度是操作系统的核心功能之一,它负责按照一定的策略和算法,合理地分配CPU资源给正在运行或即将运行的进程,从而提高操作系统的性能和资源利用率。
在操作系统中,存在多种不同的进程调度算法,本文将以C语言编写进程调度算法为主题,一步一步回答。
第一步:定义进程结构体首先,我们需要定义一个进程的数据结构体,以便在调度算法中使用。
进程结构体包括进程ID、进程优先级、进程状态等信息。
以下是一个简单的进程结构体示例:ctypedef struct {int pid; 进程IDint priority; 进程优先级int state; 进程状态} Process;第二步:初始化进程队列进程队列是存储所有待调度进程的数据结构,可以使用链表或数组来实现。
在初始化进程队列之前,需要先创建一个空的进程队列。
以下是一个简单的初始化进程队列函数:c#define MAX_PROCESSES 100 最大进程数Process processQueue[MAX_PROCESSES]; 进程队列int processCount = 0; 当前进程数void initProcessQueue() {processCount = 0;}第三步:添加进程到队列在调度算法中,需要将新创建或运行的进程添加到进程队列中,这样才能对其进行调度。
以下是一个简单的添加进程到队列的函数:void addProcess(int pid, int priority, int state) {if (processCount >= MAX_PROCESSES) {printf("进程队列已满,无法添加进程!\n");return;}Process newProcess;newProcess.pid = pid;newProcess.priority = priority;newProcess.state = state;processQueue[processCount] = newProcess;processCount++;}第四步:实现进程调度算法进程调度算法决定了操作系统如何决定哪个进程应该被调度并获得CPU 资源。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "windows.h"#include "windowsx.h"#include "tchar.h"#include "strsafe.h"#include "resource.h"#pragma warning(disable:4312)#pragma warning(disable:4244)#define EDITLEN 20#define RR 2 // 时间片#define chHANDLE_DLGMSG(hWnd, message, fn) \case (message): return (SetDlgMsgResult(hWnd, uMsg, \HANDLE_##message((hWnd), (wParam), (lParam), (fn))))struct ProcInfo {int procID; // 进程IDfloat arriveT; // 达到时间float serverT; // 服务时间float remainT; // 剩余运行时间float lastrunT; // 上次运行时间float runT; // 运行时间总和float priority; // 优先级,高响应比优先调度算法时初始为1,其他算法未用到,初始为0struct ProcInfo *next; // 下一结点} *startProc,*endProc;HWND hWnd;/*检查6个进程的到达时间和服务时间是否已经全部输入已经全部输入返回TRUE,否则返回FALSE*/bool CheckEdits(){wchar_t str[EDITLEN];for (int i=IDC_A1;i<=IDC_F1;i+=5) {GetDlgItemText(hWnd,i,str,EDITLEN);if (lstrcmp(str,_T("\0")) == 0)return false;GetDlgItemText(hWnd,i+1,str,EDITLEN);if (lstrcmp(str,_T("\0")) == 0 )return false;}return true;}/*计算平均周转时间和平均带权周转时间,并显示*/void ShowEdits(){float zzsj=0,pjzz=0;wchar_t str[10];for (int i=IDC_A4;i<=IDC_F4;i+=5) {GetDlgItemText(hWnd,i,str,10);zzsj += _wtof(str);GetDlgItemText(hWnd,i+1,str,10);pjzz += _wtof(str);}StringCchPrintf(str,10,_T("%f"),zzsj/6);SetDlgItemText(hWnd,IDC_TIME1,str);StringCchPrintf(str,10,_T("%f"),pjzz/6);SetDlgItemText(hWnd,IDC_TIME2,str);}/*清除所有编辑框的内容*/void ClearEdits(){for (int i=IDC_A1;i<IDC_TIME2+1;i++ ) {SetWindowText(GetDlgItem(hWnd,i),_T(""));}}/*在链表尾部插入node结点*/void InsertNode(ProcInfo* node){if (startProc == NULL) {startProc = endProc = node;} else {endProc->next = node;endProc = node;if (startProc->next == NULL) {startProc->next = endProc;}}}/*移除链表头结点*/void RemoveNode(){if (startProc != NULL) {float finishT;wchar_t str[10];ProcInfo *tmp = startProc;if (startProc->next != NULL) {startProc = startProc->next;startProc->lastrunT = tmp->lastrunT+tmp->remainT;} else {startProc = endProc = NULL;}finishT = tmp->lastrunT+tmp->remainT;StringCchPrintf(str,10,_T("%f"),finishT);SetDlgItemText(hWnd,IDC_A3+5*tmp->procID,str);StringCchPrintf(str,10,_T("%f"),finishT-tmp->arriveT);SetDlgItemText(hWnd,IDC_A4+5*tmp->procID,str);StringCchPrintf(str,10,_T("%f"),(finishT-tmp->arriveT)/(float)tmp->serverT);SetDlgItem i Text(hWnd,IDC_A5+5*tmp->procID,str);delete tmp;}}/*当链表头结点被抢占或时间片到时,将头结点移到尾结点参数:moreT为头结点运行到被抢占或时间片到的时间间隔*/void ChangeNode(int moreT){if (startProc != NULL) {if (startProc->next != NULL) {ProcInfo *tmp = startProc;startProc = startProc->next;tmp->next = NULL;tmp->runT += moreT;tmp->remainT -= moreT;endProc->next = tmp;endProc = tmp;startProc->lastrunT = tmp->lastrunT+moreT;} else {startProc->lastrunT += moreT;startProc->runT += moreT;startProc->remainT -= moreT;}}}/*先到先服务调度算法*/void AlgoFCFS(int *arrive,int *server){int procNum = 6;int index = 0;ProcInfo *node;startProc = endProc = NULL;while (procNum) {if (startProc != NULL) {// 直接将每个进程插入链表,链表中每个结点按顺序运行while (index<6) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 0;node->next = NULL;index++;InsertNode(node);}RemoveNode();procNum--;} else {if (index<6) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 0;node->next = NULL;index++;InsertNode(node);} elsebreak;}}}/*短进程优先调度算法*/void AlgoSJF(int *arrive,int *server){int procNum = 6;int index = 0;float minremainT;ProcInfo *node,*tmp,*seize,*mid,*tmp2;startProc = endProc = NULL;while (procNum) {if (startProc != NULL) {tmp = seize = startProc;minremainT = startProc->remainT;// 查看链表中是否有剩余运行时间比头结点小的进程,如果有存入最小运行时间while ((tmp=tmp->next) != NULL) {if (tmp->remainT < minremainT) {minremainT = tmp->remainT;seize = tmp;} else if (minremainT < startProc->remainT && tmp->remainT == minremainT) {if (tmp->arriveT < seize->arriveT)seize = tmp;}}while (index<6) {// 查看在头结点被短进程抢占,或运行结束时,是否有新进程到达if (arrive[index] < (startProc->lastrunT+minremainT)) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 0;node->next = NULL;index++;InsertNode(node);// 当有新进程到达时,根据剩余运行时间插入到链表中mid = NULL;tmp = startProc;while (tmp->next != endProc) {if (tmp->next->remainT > endProc->remainT) {mid = tmp;break;}tmp = tmp->next;}if (mid != NULL) {tmp = startProc->next;while (tmp->next != NULL) {if (tmp->next == endProc) {tmp2 = endProc;tmp->next = NULL;endProc = tmp;tmp2->next = mid->next;mid->next = tmp2;break;}tmp = tmp->next;}}// 查看刚插入的结点的剩余运行时间是否小于最小剩余时间if (node->remainT < minremainT) {minremainT = node->remainT;seize = node;} else if (minremainT < startProc->remainT && node->remainT == minremainT) {if (node->arriveT < seize->arriveT)seize = node;}} elsebreak;}// 当seize仍为头结点时,表示没有比头结点更小的剩余运行时间,故移除头结点if (seize == startProc) {RemoveNode();procNum--;} else { // 否则,将抢占进程移到头结点之后,并更改结点tmp = startProc;while (tmp != NULL) {if (tmp->next == seize) {tmp->next = seize->next;if (seize == endProc)endProc = tmp;break;}tmp = tmp->next;}seize->next = startProc->next;if (startProc == endProc)endProc = seize;startProc->next = seize;ChangeNode(minremainT);}} else {if (index<6) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 0;node->next = NULL;index++;InsertNode(node);} elsebreak;}}}/*高响应比优先调度算法*/void AlgoHRP(int *arrive,int *server){int procNum=6;int index=0;float waitT,minwaitT,waitT2,lastwaitT;ProcInfo *node,*tmp,*seize,*second;float prio=0,stmp;startProc = endProc = NULL;while(procNum) {if (startProc != NULL) {tmp = seize = second = startProc;minwaitT = startProc->remainT;// 计算在头结点剩余时间内,是否有进程的优先级超过头结点,如果有,取最先超过头结点的进程为抢占进程while((tmp=tmp->next) != NULL) {waitT = (startProc->priority-1)*tmp->serverT+0.1; // 计算超过头结点的最小等待时间lastwaitT = waitT-(startProc->lastrunT-tmp->arriveT-tmp->runT); // 计算头结点运行期间还需要等待的时间if (lastwaitT < minwaitT) { // 当小于最小时间时,更新最小时间,优先级,和抢占进程minwaitT = lastwaitT;tmp->priority = waitT/tmp->serverT+1;seize = tmp;} else if (minwaitT < startProc->remainT && lastwaitT == minwaitT) { // 当等于最小时间时,服务时间越小,优先级越高if (tmp->serverT < seize->serverT) {tmp->priority = waitT/tmp->serverT+1;seize = tmp;} else if (tmp->serverT == seize->serverT) { // 当等于最小时间,服务时间也相同时,先到达者优先if (tmp->arriveT < seize->arriveT) {tmp->priority = waitT/tmp->serverT+1;seize = tmp;}}} else {if (minwaitT == startProc->remainT) { // 当头结点剩余时间内,没有进程的优先级抢占时,计算优先级第二高的进程waitT2 = startProc->lastrunT-tmp->arriveT-tmp->runT+startProc->remainT;stmp = waitT2/tmp->serverT+1;if (stmp>prio) {tmp->priority = prio = stmp;second = tmp;}}}}while (index<6) { // 查看在头结点的剩余时间内,或被抢占的时间间隔内,是否有进程到达if (arrive[index] < (startProc->lastrunT+minwaitT)) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 1;node->next = NULL;index++;InsertNode(node);// 查看在该进程到达,到头结点运行结束,或被抢占前,优先级是否能超过头结点waitT = (startProc->priority-1)*node->serverT+0.1;lastwaitT = waitT+(node->arriveT-startProc->lastrunT);if (lastwaitT < minwaitT) {minwaitT = lastwaitT;node->priority = waitT/node->serverT+1;seize = node;} else if (minwaitT < startProc->remainT && lastwaitT == minwaitT) {if (node->serverT < seize->serverT) {node->priority = waitT/node->serverT+1;seize = node;} else if (node->serverT == seize->serverT) {if (node->arriveT < seize->arriveT) {node->priority = waitT/node->serverT+1;seize = node;}}} else {if (minwaitT == startProc->remainT) {waitT2 = startProc->remainT-(node->arriveT-startProc->lastrunT);stmp = waitT2/node->serverT+1;if (stmp > prio) {node->priority = prio = stmp;second = node;}}}} elsebreak;}// 当计算的抢占结点仍为头结点时,表示没有抢占的进程,故将第二高优先级的进程移到头结点之后,并移除头结点if (seize == startProc) {if (second != startProc) {tmp = startProc;while (tmp != NULL) {if (tmp->next == second) {tmp->next = second->next;if (second == endProc)endProc = tmp;break;}tmp = tmp->next;}second->next = startProc->next;if (startProc == endProc)endProc = second;startProc->next = second;}RemoveNode();procNum--;} else { // 当计算的抢占结点不为头结点时,表示存在能够抢占的进程,故将该抢占进程移到头结点之后,并更改结点tmp = startProc;while (tmp != NULL) {if (tmp->next == seize) {tmp->next = seize->next;if (seize == endProc)endProc = tmp;break;}tmp = tmp->next;}seize->next = startProc->next;if (startProc == endProc)endProc = seize;startProc->next = seize;ChangeNode(minwaitT);}} else {if (index<6) {node = new ProcInfo;node->procID = index;node->arriveT = arrive[index];node->serverT = server[index];node->remainT = server[index];node->lastrunT = arrive[index];node->runT = 0;node->priority = 1;node->next = NULL;index++;InsertNode(node);} elsebreak;}}}return 0;}。