#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//模拟进程转换
//模拟PCB
struct PCB {
int name; // 进程名
int priority ; //优先级
char statu; //状态
int run_time; //运行时间
int arrive_time; //到达时间
};
//按照时间来排序
struct PCB * sort_PCB(struct PCB * a,const int * len) {
for (int i = 0; i < *len; i++) {
for (int j = i + 1; j < *len; j++) {
//比较两个数谁先到达,数字越小越先到达,
if (a[i].arrive_time > a[j].arrive_time) {
struct PCB temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//如果进程到达时间一样就比较优先级的大小
else if (a[i].arrive_time == a[j].arrive_time) {
//优先级大的先进去
if (a[i].priority < a[j].priority) {
struct PCB temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//如果到达时间和优先级一样则看剩余时间剩余运行时间少的先运行
else if (a[i].priority == a[j].priority) {
if (a[i].run_time > a[j].run_time) {
struct PCB temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
//printf("%d %d\n",i,a[i].name);
}
}
return a;
}
//检测名字是否重复
struct PCB * check_name(int * i,struct PCB * a){
if(*i>=1){
//j小于i,也就是检测现在名字索引前的是否相同
for (int j = 0 ;j < *i;++j) {
if (a[j].name == a[*i].name) {
printf("PCB name err: Name repetition ");
exit(1);
}
}
}
return 0;
}
//创建PCB
struct PCB * create_PCB(int * len){
struct PCB * a = (struct PCB *) malloc(*len * sizeof(struct PCB)); //创建PCB动态列表
//依照输入的程序个数来for循环
for (int i = 0;i< *len;++i){
printf("Please input in sequence name,priority,arrive_time,run_time:\n");
scanf("%d %d %d %d",&(a[i].name),&(a[i].priority),&(a[i].arrive_time),&(a[i].run_time));
//判断名字是否重复
check_name(&i,a);
//printf("%d %d %d\n",a[i].name,a[i].priority,a[i].arrive_time);
}
//排序,谁先到排前面
return sort_PCB(a,len);
}
//struct PCB * move_PCB(int * i,struct PCB * a,int * len){
// //将运行阻塞的进程移动到末尾
// struct PCB temp = a[*i];
// for (int x = *i+i ; x<*len; x++)
// {
// a[x - 1] = a[*i];
// }
// a[*len - 1] = temp;
// return 0;
//}
//等待队列
struct PCB * wait_queue(int * i , int * len , struct PCB *a) {
for (int j = *i+1 ; j <= *len; j++) {
//判断j是等于len的长度如果不是则输入j的信息
if(j != *len){
if (a[j].run_time > 0) {
printf("wait process is %d\n", a[j].name);
printf("It priority is %d\n", a[j].priority);
strcpy(&a[j].statu, "W");
printf("It status is %c\n", a[j].statu);
printf("It Remaining running time is %d\n", a[j].run_time);
printf("----------------------------------------\n");
}
}
//如果是,说明j已经运行到最后一个值了,就需要讲当前运行的值加入队列后面
else if (j == *len ) {
//判断i是不是最后一个值
if (*i == *len - 1) {
//循环执行,如果是最后一个值,那就按照顺序遍历列表,这样就相当于吧当前值加入到队列最后面了
for (int x = 0; x < *i; x++) {
//如果运行完成了就不遍历
if (a[x].run_time > 0) {
printf("wait process is %d\n", a[x].name);
printf("It priority is %d\n", a[x].priority);
strcpy(&a[x].statu, "W");
printf("It status is %c\n", a[x].statu);
printf("It Remaining running time is %d\n", a[x].run_time);
printf("-----------------i-----------------------\n");
}
}
}
else {
for (int x = *i - 1; x <= *i; x++) {
if (a[x].run_time > 0) {
printf("wait process is %d\n", a[x].name);
printf("It priority is %d\n", a[x].priority);
strcpy(&a[x].statu, "W");
printf("It status is %c\n", a[x].statu);
printf("It Remaining running time is %d\n", a[x].run_time);
printf("----------------------------------------\n");
}
}
}
}
}
return 0;
}
//运行
struct PCB * run_queue(int * i,struct PCB * a,int * time){
//直接输入当前队列顶部的值
printf("running process is %d\n", a[*i].name);
printf("It priority is %d\n", a[*i].priority);
strcpy(&a[*i].statu, "R");
printf("It status is %c\n", a[*i].statu);
a[*i].run_time -= *time;
//判断如果time时间小于0就直接为0
if (a[*i].run_time < 0) a[*i].run_time = 0;
printf("It Remaining running time is %d\n", a[*i].run_time);
//没有剩余运行时间则程序直接结束
if (a[*i].run_time == 0) {
printf("-----------------over-------------------\n");
printf("%d running time is over\n", a[*i].name);
//将运行阻塞的进程移动到末尾(遗弃)
//move_PCB(&i,a,&len);
} else {
printf("---------------add wait-----------------\n");
//printf("process %d adds blocking queue\n", a[i].name);
strcpy(&a[*i].statu, "W");
printf("process statu is %c\n", a[*i].statu);
//将运行阻塞的进程移动到末尾(遗弃)
//move_PCB(&i,a,&len);
}
return NULL;
}
void run_program();
void check_continue(int * len,struct PCB * a){
char x;
//询问是否继续
printf("all process is run over\n");
printf("Do you want to continue?(y or n)");
scanf("%c",&x);
//输入n程序直接结束
if (x == 'n') {
exit(2);
}
//输入y则继续运行函数
else if(x == 'y') {
free(a);
run_program();
}
}
//判断队列run_time是否为0,如果有不为0的就返回false;
bool pan(struct PCB * a,int * len) {
for (int i = 0; i < *len; i++) {
if (a[i].run_time != 0) {
return false;
}
}
return true;
}
//运行函数
struct PCB * run_process(struct PCB * a,int * len,int * time) {
//定义一个为true就一直执行
while (1) {
//遍历阻塞队列中的值
for (int i = 0; i < *len; i++) {
//如果还有运行时间就遍历,
if (a[i].run_time > 0) {
//输出运行程序
printf("----------------running----------------\n");
run_queue(&i,a,time);
//输出等待队列
printf("----------------wait queue--------------\n");
wait_queue(&i,len,a);
}
//判断如果队列内run_time都为0则执行,也就是判断队列内程序是否都执行完毕
else if (pan(a,len)) {
check_continue(len,a);
}
}
}
}
//输入程序个数
int input_num(){
int len; //进程数量
printf("input process number:");
scanf("%d", &len);
if (len == 0) printf("program over\n");
return len;
}
void run_program(){
int time = 10; //时间片
int len; //进程数量
len = input_num();
//阻塞队列
struct PCB * r = (struct PCB *) malloc(len * sizeof(struct PCB));
free(r);
//struct PCB *w = (struct PCB *) malloc(len * sizeof(struct PCB));
//创建运行队列
r = create_PCB(&len);
//printf("%d",r[1].name);
//运行程序
run_process(r, &len, &time);
//printf("%d",b[0].name);
}
int main(void) {
run_program();
}