操作系统(进程调度模拟课设)

大耗子 2020年06月04日 172次浏览

文章链接:https://codemouse.online/archives/2020-06-04160950

需求

(1)用C语言(或其它语言,如Java)编程实现对N个进程采用某种进程调度算法(如动态优先权调度算法、先来先服务算法、短进程优先算法、时间片轮转调度算法)调度执行的模拟。
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段:

  • 进程标识数ID。
  • 进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
  • 进程已占用CPU时间CPUTIME。
  • 进程还需占用的CPU时间ALLTIME。当进程运行完毕时,ALLTIME变为0。
  • 进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK个时间片后,进程将进入阻塞状态。
  • 进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。
  • 进程状态STATE。
  • 队列指针NEXT,用来将PCB排成队列。
    (3)优先数改变的原则:
  • 进程在就绪队列中呆一个时间片,优先数增加1。
  • 进程每运行一个时间片,优先数减3。
    (4)为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。

代码

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <time.h>


#define TASK_RUNNING 'i'	// 运行
#define TASK_WAIT    'w'	// 等待
#define TASK_READY   'r'	// 就绪

struct process {
	int pid;
	int priority;
	int alltime;
	int cputime; // 已占用的时间
	int startblock; // 本次要运行的时间片
	int blocktime;	// 还需等待时间
	char state;
	char pname[10];
	struct process *next;
	//ready 就绪
}*ready = NULL, *p;

typedef struct process PCB;
int curr_pid = 0;
int time_slice = 1;

void update(PCB *node)
{
	PCB *temp = node;
	while (temp && temp->next != NULL)
	{
		temp->next->blocktime = temp->blocktime + 1;
		temp = temp->next;
	}
}

// 优先级高的在前
void sort()
{
	PCB *first, *second;
	int insert = 0;
	// 如果优先级大于就绪的就抢占
	if (ready == NULL || ((p->priority) > (ready->priority)))
	{
		p->next = ready;
		if (ready!= NULL)
			ready->state = TASK_WAIT;
		ready = p;


		ready->blocktime = 0;
		ready->state = TASK_READY;
		update(ready->next);
	}

	else
	{
		// 找到头
		first = ready;
		second = (first->next);
		// 找到适合的位置
		while (second != NULL)
		{
			if ((p->priority)>(second->priority))
			{
				// 找到合适位置, 插入first和second中间
				p->next = second;
				first->next = p;
				update(p);
				second = NULL;
				insert = 1;
			}
			else
			{
				first = first->next;
				second = second->next;
			}
		}
		// 只有一个节点,直接插入节点的后面
		if (insert == 0)
		{
			p->blocktime = 1;
			first->next = p;
		}

	}
}
// 申请内存,并对优先级排序
void input()
{
	int i;
	printf("手动输入请输入1,自动输入请输入2\n");
	int num = 0;
	scanf("%d", &num);
	getchar();
	for (i = 0; i<5; i++)
	{
		p = (PCB *)malloc(sizeof(PCB));
		if (num == 1)
		{
			printf("name alltime priority\n");
			scanf("%s", p->pname);
			scanf("%d", &p->alltime);
			scanf("%d", &p->priority);
		}
		else
		{
			strcpy(p->pname, "mouse");
			p->pname[5] = i + 48;
			p->pname[6] = 0;
			p->alltime = rand() % 10 + 1;
			p->priority = rand() % 15 + 1;
		}
		p->pid = curr_pid++;
		p->cputime = 0;
		p->startblock = 1;
		p->blocktime = 0; // 通过排序确定
		p->state = TASK_WAIT;
		p->next = NULL;
		sort();
	}
	getchar();
}
int space()
{
	int l = 0;
	PCB* pr;
	pr = ready;
	while (pr != NULL)
	{
		l++;
		pr = pr->next;
	}
	return(l);
}
// 打印节点信息
void disp(PCB * pr)
{
	printf("\n pid \t    pname \t state \t priority \t runtime \t alltime \t waittime\n");
	printf("%4d\t", pr->pid);
	printf("%10s\t", pr->pname);
	printf(" %c\t", pr->state);
	printf(" %-4d\t\t", pr->priority);
	printf(" %d\t", pr->cputime);
	printf("\t%d\t", pr->alltime);
	printf("\t%d\t", pr->blocktime);
	printf("\n");
}
// 查看所有节点信息
void check()
{
	PCB *pr;
	printf("\n running process is :\n", p->pid, p->pname);
	disp(p);
	// 待运行节点
	pr = ready;
	printf("\n ready process is :\n");
	while (pr != NULL)
	{
		disp(pr);
		pr->priority++;
		pr = pr->next;
	}
}
void all_info()
{
	PCB *pr;
	pr = ready;
	printf("Process list :\n");
	while (pr != NULL)
	{
		disp(pr);
		pr = pr->next;
	}
}
// 摧毁节点
void destroy()
{
	printf("\n process pid:%d name:%s end\n", p->pid, p->pname);
	free(p);
}
void before_run()
{
	p = ready;
	ready = p->next;
	p->next = NULL;
	p->cputime++;
	p->alltime--;
	p->state = TASK_RUNNING;
	if (ready)
	{
		ready->state = TASK_READY;
		ready->blocktime = 0;
		update(ready);
	}
}
void after_run()
{
	if (0 == p->alltime)
		destroy();
	else
	{
		p->priority -= 3;
		p->state = TASK_WAIT;
		sort();
	}
}
int main()
{
	int len, h = 0;
	input();
	len = space();
	all_info();
	printf("\n Enter any key to start the running process\n");
	getchar();
	system("cls");
	srand((unsigned)time(NULL));
	while ((len != 0) && (ready != NULL))
	{
		printf("\n The execute slice:%d\n", h);
		h++;
		before_run();
		check();
		after_run();
		printf("\n Enter any key continue");
		getchar();
		system("cls");
	}
	printf("\n All process run finsh!!!\n");
	getchar();
	return 0;
}