#define _CRT_SECURE_NO_WARNINGS 1
/*
* 多道程序设计模拟
* 作者:hjz
* 时间:2020/11/8
*
* 本次为操作系统的实验,模拟了A,B,C三个程序的多道程序的执行,比较顺序执行和多道程序设计
* 程序执行的顺序为:计算->IO操作->计算->结束,分为三段
* 例如:
* A先计算30ms,再io操作40ms,再计算10ms。
* B先计算60ms,再io操作30ms,再计算10ms。
* A先计算20ms,再io操作40ms,再计算20ms。
*
* 本次实验只模拟了三个程序和单通道模式
*/
#include<stdio.h>
#include<stdlib.h>
#define true 1
#define false 0
#define CPU 2
#define IO -1
typedef struct {
char id;//任务名称
int cpu_time1;//第一次计算时间
int cpu_time2;//第二次计算时间
int io_time;//io操作时间
short flag;//第一次是否已计算完,计算完为1
}pro;//程序结构体
typedef struct {
pro* arr[3];//队列
int first;//队头
int last;//队尾
int n;//元素数量
}queue;//队列
queue cpu_q;//cpu队列
queue io_q;//io队列
void init(pro*, pro*, pro*);
void input(pro*);
void run_seq();
void run_par();
int enqueue(pro*, int);
pro* dequeue(int);
int empty(int);
int full(int);
int back(int, pro*);
int main() {
pro* pro_a = 0;
pro* pro_b = 0;
pro* pro_c = 0;
init(pro_a, pro_b, pro_c);
run_seq();
run_par();
return 0;
}
/*
* 判定队列是否是空
*
* 参数:
* i:为1判定cpu队列,否则为io队列
* 返回值:如果为空返回正数,否则返回0
*/
int empty(int i) {
if (i == CPU) {
return cpu_q.n == 0;
}
else {
return io_q.n == 0;
}
}
/*
* 判定队列是否满
*
* 参数:
* i:为CPU判定cpu队列,否则为io队列
* 返回值:如果满返回正数,否则返回0
*/
int full(int i) {
if (i == CPU) {
return cpu_q.n == 3;
}
else {
return io_q.n == 3;
}
}
/*
* 入队操作
*
* 参数:
* p:要入队的程序
* i:为CPU入cpu队列,否则为io队列
* 返回值:如果正常入队返回1,否则返回0
*/
int enqueue(pro* p, int i) {
if (full(i)) return false;
if (i == CPU) {
cpu_q.arr[cpu_q.last] = p;
cpu_q.last = (cpu_q.last + 1) % 3;
cpu_q.n++;
}
else {
io_q.arr[io_q.last] = p;
io_q.last = (io_q.last + 1) % 3;
io_q.n++;
}
return true;
}
/*
* 出队操作
*
* 参数:
* i:为1出cpu队列,否则为io队列
* 返回值:返回队头元素或NULL
*/
pro* dequeue(int i) {
if (empty(i)) return NULL;
pro* temp;
if (i == CPU) {
temp = cpu_q.arr[cpu_q.first];
cpu_q.arr[cpu_q.first] = NULL;
cpu_q.first = (cpu_q.first + 1) % 3;
cpu_q.n--;
}
else {
temp = io_q.arr[io_q.first];
io_q.arr[io_q.first] = NULL;
io_q.first = (io_q.first + 1) % 3;
io_q.n--;
}
return temp;
}
/*
* 将元素添加到队列头
*
* 参数:
* i:为CPU则添加到cpu队列,否则添加到io队列
* p:要添加的任务
* 返回值:添加成功返回1
*/
int back(int i, pro* p) {
if (full(i)) return false;
if (i == CPU) {
cpu_q.first = (cpu_q.first - 1) % 3;
cpu_q.arr[cpu_q.first] = p;
cpu_q.n++;
return true;
}
else {
io_q.first = (io_q.first - 1) % 3;
io_q.arr[io_q.first] = p;
io_q.n++;
return true;
}
return false;
}
/*
* 程序计算时间和io时间初始化
*
* 参数:
* p:要被初始化的程序
*/
void input(pro* p) {
printf("请输入程序%c第一次计算的时间:", p->id);
scanf("%d", &(p->cpu_time1));
printf("请输入程序%c所需要的io时间:", p->id);
scanf("%d", &(p->io_time));
printf("请输入程序%c第二次计算的时间:", p->id);
scanf("%d", &(p->cpu_time2));
p->flag = 0;
putchar('\n');
}
/*
* 队列和多道程序初始化
*
* 参数:
* a:被初始化程序1
* b:被初始化程序2
* c:被初始化程序3
*/
void init(pro* a, pro* b, pro* c) {
printf("---------程序初始化---------\n");
a = (pro*)malloc(sizeof(pro));
b = (pro*)malloc(sizeof(pro));//动态分配内存
c = (pro*)malloc(sizeof(pro));
a->id = 'A';
b->id = 'B';
c->id = 'C';
input(a);
input(b);
input(c);
cpu_q.arr[0] = a;
cpu_q.arr[1] = b;
cpu_q.arr[2] = c;
cpu_q.first = 0;
cpu_q.last = 0;
cpu_q.n = 3;
io_q.first = 0;
io_q.last = 0;
io_q.n = 0;
}
/*
* 顺序执行模式
*/
void run_seq() {
printf("---------顺序执行模式---------\n");
int i, sum = 0;
for (i = 0; i < 3; i++) {
printf("程序%c计算%dms,io%dms,计算%dms\n",
cpu_q.arr[i]->id, cpu_q.arr[i]->cpu_time1, cpu_q.arr[i]->io_time, cpu_q.arr[i]->cpu_time2);
sum = sum + cpu_q.arr[i]->cpu_time1 + cpu_q.arr[i]->io_time + cpu_q.arr[i]->cpu_time2;
}
putchar('\n');
printf("总耗时%dms\n", sum);
}
/*
* 多道执行模式
*/
void run_par() {
printf("---------多道程序模式---------\n");
pro* temp, * temp1;
int time, sum = 0;
while (!empty(CPU) || !empty(IO)) {
//如果io队列为空,则进行计算
if (empty(IO)) {
temp = dequeue(CPU);
if (temp != NULL) {
time = (temp->flag == 0) ? (temp->cpu_time1) : (temp->cpu_time2);
printf("程序%c计算%dms\n", temp->id, time);
sum += time;
if (temp->flag == 0) {//如果是第一次计算,放入io队列,否则该程序结束
temp->flag = 1;
enqueue(temp, IO);
}
else free(temp);
continue;
}
exit(0);
}
//如果cpu队列为空,则进行io调度,io调度完成后继续完成计算至程序结束
if (empty(CPU)) {
temp = dequeue(IO);
if (temp != NULL) {
printf("程序%c进行io%dms\n", temp->id, temp->io_time);
printf("程序%c计算%dms\n", temp->id, temp->cpu_time2);
sum = sum + temp->io_time + temp->cpu_time2;
free(temp);
continue;
}
exit(0);
}
//如果io队列和cpu队列都不为空,则io操作和计算同时进行
temp = dequeue(CPU);
temp1 = dequeue(IO);
if (temp->flag == 0) time = temp->cpu_time1 - temp1->io_time;
else time = temp->cpu_time2 - temp1->io_time;
if (time >= 0) {
if (temp->flag == 0) {
printf("程序%c计算%dms的同时,程序%c进行io%dms", temp->id, temp->cpu_time1, temp1->id, temp1->io_time);
sum += temp->cpu_time1;
}
else {
printf("程序%c计算%dms的同时,程序%c进行io%dms", temp->id, temp->cpu_time2, temp1->id, temp1->io_time);
sum += temp->cpu_time2;
}
while (time > 0) {//如果在io操作完成后,正在计算的程序还没完成计算,继续调度io队列中的下一个
int temp_time;
if (!empty(IO)) {
pro* temp2 = dequeue(IO);
temp_time = temp2->io_time;
if (temp_time > time) {//如果下一个io操作所需的时间过长,则先进行一段io操作,再放回队首,下次再调度
printf(",程序%c进行io%dms", temp2->id, time);
temp2->io_time = temp2->io_time - time;
back(IO, temp2);
break;
}
else {
printf(",程序%c进行io%dms", temp2->id, temp_time);
time -= temp_time;
enqueue(temp2, CPU);
}
}
break;
}
enqueue(temp1, CPU);
if (temp->flag == 0) {
temp->flag = 1;
enqueue(temp, IO);//如果是第一次计算,则进入io队列
}
else free(temp);
putchar('\n');
}
else {
sum += temp1->io_time;
if (temp->flag == 0) {
printf("程序%c计算%dms的同时,程序%c进行io%dms", temp->id, temp->cpu_time1, temp1->id, temp1->io_time);
}
else {
printf("程序%c计算%dms的同时,程序%c进行io%dms", temp->id, temp->cpu_time2, temp1->id, temp1->io_time);
}
time = -time;
while (time > 0) {//如果计算完成后,io操作还在继续,则继续调度cpu队列
int temp_time;
if (!empty(CPU)) {
pro* temp2 = dequeue(CPU);
temp_time = (temp2->flag == 0) ? (temp2->cpu_time1) : (temp2->cpu_time2);
if (temp_time > time) {
printf(",程序%c计算%dms\n", temp2->id, time);
if (temp2->flag == 0) temp2->cpu_time1 = temp2->cpu_time1 - time;
else temp2->cpu_time2 = temp2->cpu_time2 - time;
back(CPU, temp2);
break;
}
else {
printf(",程序%c计算%dms", temp2->id, temp_time);
time -= temp_time;
if (temp2->flag == 0) {
temp2->flag = 1;
enqueue(temp2, CPU);
}
else free(temp2);
}
}
break;
}
enqueue(temp1, CPU);//完成io操作后调入cpu队列
if (temp->flag == 0) {
temp->flag = 1;
enqueue(temp, IO);
}
else free(temp);
putchar('\n');
}
}
printf("总耗时%dms\n", sum);
}
相似问题