一、简介
1.1 背景
在计算机科学领域,进程调度是操作系统中一个关键的组成部分,它负责协调系统中各个进程的执行顺序,以最大程度地提高系统资源利用率 。在这篇博客中,将深入探讨基于优先级的轮转调度算法,该算法结合了进程的优先级
和时间片轮转
的思想,以实现高效的任务执行。
1.2 目的
本文的主要目的是解释和分析一个使用C++编写的简单进程调度程序。将详细介绍程序的结构和实现细节,同时提供示例以帮助读者理解基于优先级的轮转调度算法的工作原理。
1.3 代码概览
程序需要使用一个结构体 content
来表示进程,包括进程名、优先级、到达时间、需要时间、已用时间和进程状态等信息。主要功能包括增加进程、打印结果以及实现基于优先级的轮转调度。以下是进程调度程序的框架:
程序框架 { m a i n 主函数:用于循环菜单操作 m a r k 主菜单:提示用户包括输入时间片、打印结果等 p r t 函数:进程调度算法以及输出进程调度的结果 a d d 函数:增加进程信息 c o n t e n t 结构体:进程名、优先级、到达时间、需要时间、已用时间和进程状态等信息 程序框架\begin{cases} main主函数:用于循环菜单操作\\mark主菜单:提示用户包括输入时间片、打印结果等\\prt函数:进程调度算法以及输出进程调度的结果\\add函数:增加进程信息\\content结构体:进程名、优先级、到达时间、需要时间、已用时间和进程状态等信息 \end{cases} 程序框架⎩ ⎨ ⎧main主函数:用于循环菜单操作mark主菜单:提示用户包括输入时间片、打印结果等prt函数:进程调度算法以及输出进程调度的结果add函数:增加进程信息content结构体:进程名、优先级、到达时间、需要时间、已用时间和进程状态等信息
二、进程调度算法概述
2.1 优先级调度算法
优先级调度算法是一种常见的进程调度策略,它根据进程的优先级来确定执行顺序。在我们的程序中,每个进程都被赋予一个优先级 (f),并根据该优先级进行排序。较高优先级的进程将在较低优先级的进程之前执行。
2.2 轮转调度算法
轮转调度算法引入了时间片
的概念,即每个进程被分配的执行时间。在我们的实现中,用户可以输入时间片的大小,这将影响每个进程的运行时间。当一个进程用完它的时间片后,调度程序将切换到下一个就绪队列中的进程,以此类推。
三、代码详解
3.1 结构体定义
在程序中,使用一个名为 content
的结构体来表示每个进程的信息。这个结构体包含进程名 (name
)、优先级 (f
)、到达时间 (arrtime
)、所需时间 (needtime
)、已用时间 (gettime
) 以及进程状态 (process
)。
cpp
struct content
{
string name; // 进程名
int f; // 优先级
int arrtime; // 到达时间
int needtime; // 所需时间
int gettime; // 已用时间
string process; // 进程状态
};
这个结构体的定义来组织和存储每个进程的相关信息。
3.2 主菜单函数 (mark)
主菜单函数 mark
用于引导用户进行操作选择。用户可以选择增加进程、打印进程状态,或结束任务。该函数返回用户的选择。
cpp
int mark()
{
int pd;
cout << "增加进程并调度进程,请按1\n打印进程,请按2\n任务结束,请按0" << endl;
cin >> pd;
if (pd < 0 || pd > 2)
{
return mark();
}
return pd;
}
3.3 增加进程函数 (add)
增加进程函数 add
用于向进程数组中添加新的进程。用户需要输入进程的名称、优先级以及所需时间。这个函数返回一个标志,指示是否继续增加进程。
cpp
int add(struct content a[], int i)
{
char pd;
cout << "请输入进程名:";
cin >> a[i].name;
cout << "请输入进程的优先级:";
cin >> a[i].f;
cout << "请输入进程需要的时间:";
cin >> a[i].needtime;
a[i].arrtime = i; // 设置到达时间
a[i].gettime = 0; // 初始化已用时间
a[i].process = 'W'; // 初始化进程状态(等)
cout << "还要继续增加进程吗,是(Y)否(N)";
cin >> pd;
if (pd == 'N')
return 0;
return 1;
}
函数允许用户连续添加多个进程,直到用户选择停止。
3.4 打印结果函数 (prt)
打印结果函数 prt
负责对进程进行排序,并根据优先级和到达时间打印进程状态。该函数还包括递归调用以模拟进程的运行。
cpp
void prt(struct content a[], int n, int time)
{
// (排序和打印结果的实现)
int i,j,pd=0;
//排序
for(i=0;i<=n-1;i++)
{
for(j=0;j<=n-i-1;j++)
{
if(a[j].f<a[j+1].f||(a[j].f==a[j+1].f&&a[j].arrtime>a[j+1].arrtime))//先根据优先级,后根据到达时间判断
{
struct content temp;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
a[0].process='R';//改变第一个进程的状态(运行)
for(i=0;i<=n;i++)
{
if(a[i].gettime<a[i].needtime)
{
pd=1;
break;
}
}
if(pd==0)
{
a[0].process='F';//修改最后进程完成状态
}
cout<<"进程名 优先级 到达时间 需要时间 已用时间 进程状态"<<endl;
for(i=0;i<=n;i++)
{
cout<<a[i].name<<"\t"<<a[i].f<<"\t"<<a[i].arrtime<<"\t "<<a[i].needtime<<"\t "<<a[i].gettime<<"\t "<<a[i].process<<endl;
}
if (pd == 0)
{
return; // 退出递归
}
// 修改数据
a[0].f -= 1;
a[0].gettime += time;
a[0].process = 'W';
if (a[0].gettime >= a[0].needtime)
{
a[0].f = -1000;
a[0].gettime = a[0].needtime;
a[0].process = 'F';
}
prt(a, n, time); // 递归打印
}
这个函数通过递归调用自身,模拟了进程的调度和执行过程。在打印结果时,它显示了每个进程的详细信息,包括进程名、优先级、到达时间、需要时间、已用时间和进程状态。
3.5 主函数(main)
cpp
int main()
{
int time; // 时间片大小
int i = -1; // 记录进程个数和到达时间
struct content a[10];
cout << "请输入时间片大小:";
cin >> time;
while (1)
{
int pd = mark(); // 主菜单判断
if (pd == 0)
break; // 退出
if (pd == 1)
{
while (1)
{
i++;
int pd = add(a, i);
if (pd == 0)
break; // 增加进程完毕,退出
}
}
if (pd == 2)
{
prt(a, i, time);
continue;
}
prt(a, i, time);
}
}