RR时间片轮转法调度C语言实现

什么是RR?
RR=Round-Robin;
实现思想:
在FCFS的基础上,加入时间片的概念,从第一个到达的进程开始,CPU分配其一个时间片的长度,第一个进程放到其余任务后面,然后给第二个进程分配一个时间片,第二个进程放到其余任务后面,依次类推,直到所有进程完成。假如进程结束了,时间片没用完,则回收剩余时间片。

完整代码:

#include
#include
#define circletime 5
typedef struct PCB {
	int id;//任务序号
	int arrivetime;//任务到达时间
	int runtime;//任务需要执行的时间
	int counttime;//记录任务处理一段时间后,剩下的需要处理的时间
	int aetime;//假定义当前到达时间
	struct PCB* next;
}*task, pcb;
pcb* creattask(int x, int y, int z) {
	task newtask = (task)malloc(sizeof(pcb));
	newtask->id = x;
	newtask->arrivetime = y;
	newtask->runtime = z;
	newtask->counttime = z;
	newtask->aetime = y;
	newtask->next = NULL;
	return newtask;
}
void deltask(pcb* n, int x) {
	task d;
	if (n != NULL) {
		while (n->next->id != x) {
			n = n->next;
		}
		d = n->next;
		n->next = d->next;
		free(d);
	}
}
void count(pcb* n, int t) {  //q用于记录最先到达的任务位置,p用于遍历链表
	pcb* q, * p,* last;
	int qp = 0; //用于记录上一次任务的id号
	int temp = t; float time = 0; //time记录当前时间,temp记录任务个数,便于后续操作
	float zt = 0, dt = 0;  //zt用于记录总周转时间,dt记录总带权周转时间
	while (t != 0) {
		p = n->next;
		q = p;
		while (p != NULL) { //找到最先到达的任务
			if (p->aetime < q->aetime) {
				q = p;
			}
			p = p->next;
		}
		p = n->next;
		last = p;
		while (p != NULL) { //找到最后到达的任务
			if (p->aetime > last->aetime) {
				last = p;
			}
			p = p->next;
		}
		if (time < q->aetime)
			time = q->aetime;
		printf("当前执行的是任务%d\n", q->id);
		if (q->counttime <= circletime) {//处理剩余时间不足时间片长度时,CPU停止
			time =time + q->counttime;
			q->counttime = 0;
		}
		else {
			q->counttime = q->counttime - circletime;
			q->aetime = last->aetime + circletime;
			time = time + circletime;
		}
		if (q->counttime == 0) {
			printf("任务%d结束\n", q->id);
			printf("该任务周转时间为 %.0f \n", time - q->arrivetime);
			zt = zt + time - q->arrivetime;
			printf("该任务带权周转时间为 %.2f \n\n", (time - q->arrivetime) / q->runtime);
			dt = dt + (time - q->arrivetime) / q->runtime;
			deltask(n, q->id);
			--t;
		}
	}
	printf("\n");
	printf("平均周转时间为 %.2f \n", zt / temp);
	printf("平均带权周转时间为 %.2f \n", dt / temp);
}
int main() {
	int n, i, y, z;
	task tail = NULL;
	task head = NULL;
	printf("请输入任务数量:");
	scanf_s("%d", &n);
	tail = (task)malloc(sizeof(pcb));
	head = tail;
	for (i = 1; i <= n; i++) {
		printf("请输入%d号任务的到达时间、运行时间:", i);
		scanf_s("%d%d", &y, &z);
		tail->next = creattask(i, y, z);
		tail = tail->next;
	}
	count(head, n);
}

如果时间片过长,则退化为FCFS,进程在一个时间片就可以完成。
如果时间片过短,用户的一次请求需要多个时间片才处理完,上下文切换次数增加。
使单个时间片内多数进程能够完成他们的工作 ,那么平均周转时间会得到改进。

时间片的长短通常有一下三个因素决定:
1.系统的响应时间
2.就绪队列里面的进程数目
3.系统处理能力

你可能感兴趣的:(学习)