操作系统:用C语言实现FCFS(先来先服务),SJF(短作业抢占)和RR(时间片轮转,时间片=1)

这篇具有很好参考价值的文章主要介绍了操作系统:用C语言实现FCFS(先来先服务),SJF(短作业抢占)和RR(时间片轮转,时间片=1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.1 实验目的

   加深对进程调度的理解,熟悉进程调度的不同算法,比较其优劣性。

1.2 实验内容

假如一个系统中有5个进程,它们的到达时间内如表1所示,忽略I/O以及其他开销时间。若分别按先来先服务(FCFS)、抢占的短作业优先(SJF)、时间片轮转(RR,时间片=1)进行CPU调度,请按照上述三个算法,编程计算出各进程的完成时间内、周转时间、带权周转周期、平均周转周期和平均带权周转时间。

表1 进程到达和需服务时间

进程

到达时间

服务时间

A

0

3

B

2

6

C

4

4

D

6

5

E

8

2

1.3算法描述

FCFS是先来先服务算法,采用队列的思想,队首入,队尾出,后到的放在队首。

SJF是抢占短作业优先算法,在采取队列的同时要注意当前进程的剩余服务时间和新来进程的服务时间长短,如果新来的更短则进行抢占,否则继续进行,如果该进程进行完则要在队列中挑选最短的作业进行执行。

RR是时间片轮转算法,每一个进程在队列里享受一定的时间片,当时间片用完时,进程将会被放到队首,等待下一时间片的分配。

1.4 实验结果(linux虚拟机运行)

编译指令:#g++ -o process process.cpp

运行指令:./process

c语言实现先来先服务算法,c语言,linux,算法

 

1.5 实验小结

FCFS先来先服务并没有太多复杂的放地方,完全可以用数组遍历的方式再加上一个时间参数来方便记录各进程的完成时间,最后每个数据类型都应该是double或者float防止在计算的时候数据出现较大的偏差。SJF短作业抢占时要注意比较新来进程需要服务时间和剩余时间,如果新来更短则抢占,这里要注意的是如果在没有新来进程情况下,队列中的进程需要服务时间都应该比正在进行的进程长,并且在该进程进行完时应该挑选队列里最短的作业进行完成。RR时间片轮转算法最关键的还是判断新来进程和上一秒完成进程谁先放在队列后面,因此理论上讲RR轮转算法计算应该会有两种结果,本代码用两个RR函数分别代表了新来进程优先和上一秒完成进程优先的两种情况。另外,后两种算法都应该注意循环的结束条件,即所有进程完成的判断条件和剩余服务时间的记录。

1.6实验代码

 运行时输入:

5

0 3

2 6

4 4

6 5

8 2文章来源地址https://www.toymoban.com/news/detail-765590.html

/* 运行时输入:
5
0 3
2 6
4 4
6 5
8 2
*/
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define Maxsize 10
typedef struct process {
	char name;		/*进程名*/
	int arrive;		/*到达时间*/
	int serve;		/*服务时间*/
	int end;		/*结束服务时间*/
	int use;		/*使用时间(链表专用)*/
	struct process* next;	/*下一结点(链表专用)*/
}p[Maxsize],pNode;
p pp;
int process;
void FCFS();
void SJF();
void RR();
void RR1();
int main() {
	scanf_s("%d", &process);
	for (int i = 0; i < process; i++) {		/*输入进程信息*/
		scanf_s("%d %d", &pp[i].arrive, &pp[i].serve);
		pp[i].name = (char)(65 + i);
		pp[i].use = 0;
	}
	FCFS();
	SJF();
	RR();
	RR1();
	return 0;
}

void FCFS() {
	int time = 0;		/*时间参数*/
	float avert = 0, avertt = 0;		/*平均周转,平均带权周转*/
	printf("FCFS:\n进程\t完成时间区间\t周转时间\t带权周转周期\t\n");
	for (int i = 0; i < process; i++) {
		time += pp[i].serve;		/*时间参数计数*/
		pp[i].end = time;		/*进程结束时间记录*/
		printf("%c\t%d-%d\t\t%d\t\t%f\n",pp[i].name, pp[i].arrive, pp[i].end, pp[i].end - pp[i].arrive, (float)(pp[i].end - pp[i].arrive) / pp[i].serve);
		avert += pp[i].end - pp[i].arrive; avertt += (float)(pp[i].end - pp[i].arrive) / pp[i].serve;
	}
	printf("平均周转周期: %f\t平均带权周转时间: %f\n\n", avert / process, avertt / process);
}
void SJF() {
	int time = 0;	/*时间参数*/
	int finish[Maxsize] = { 0 };		/*对应每个进程的完成进度*/
	float avert = 0, avertt = 0;		/*平均周转,平均带权周转*/
	for (int i = 0; i < process; i++) {		/*计算需要时间长度方便结束循环*/
		time += pp[i].serve;
	}
	printf("SJF:\n进程\t完成时间区间\t周转时间\t带权周转周期\t\n");
	int t = 0;
	while (t < time) {
		int min=0, mintime = 1e9;
		for (int i = 0; i < process; i++) {		/*寻找剩余服务时间最短的进程,剩余服务时间=server-finish*/
			if (pp[i].arrive <= t&&pp[i].serve-finish[i]<mintime&& pp[i].serve != finish[i]) {
				min = i; mintime = pp[i].serve - finish[i];
			}
		}
		finish[min]++;
		if (finish[min] == pp[min].serve) {		/*进程完成判断*/
			pp[min].end = t + 1;
		}
		t++;		/*以1为时间片方便判断是否进行抢占*/
	}
	for (int i = 0; i < process; i++) {
		printf("%c\t%d-%d\t\t%d\t\t%f\n",  pp[i].name, pp[i].arrive, pp[i].end, pp[i].end - pp[i].arrive, (float)(pp[i].end - pp[i].arrive) / pp[i].serve);
		avert += pp[i].end - pp[i].arrive; avertt += (float)(pp[i].end - pp[i].arrive) / pp[i].serve;
	}
	printf("平均周转周期: %f\t平均带权周转时间: %f\n\n", avert / process, avertt / process);
}
void RR() {
	int time = 0;	/*时间参数*/
	int finish[Maxsize] = { 0 };		/*对应每个进程的完成进度*/
	float avert = 0, avertt = 0;		/*平均周转,平均带权周转*/
	for (int i = 0; i < process; i++) {		/*计算需要时间长度方便结束循环*/
		time += pp[i].serve;
	}
	printf("RR(上一秒完成进程优先):\n进程\n完成时间区间\t周转时间\t带权周转周期\t\n");
	int t = 0;
	while (true) {
		int B = 0;		/*结束条件*/
		for (int i = 0; i < process; i++) {
			if (pp[i].arrive <= t && pp[i].serve != finish[i])		/*判断是否完成和是否到达*/
			{
				finish[i]++;
				t++;
				if (pp[i].serve == finish[i])pp[i].end = t;		/*单个进程完成判定*/
			}
			if (t == time) {		/*所有进程全部完成判定*/
				B = 1; break;
			}
		}
		if (B)break;
	}
	for (int i = 0; i < process; i++) {
		printf("%c\t%d-%d\t\t%d\t\t%f\n", pp[i].name, pp[i].arrive, pp[i].end, pp[i].end - pp[i].arrive, (float)(pp[i].end - pp[i].arrive) / pp[i].serve);
		avert += pp[i].end - pp[i].arrive; avertt += (float)(pp[i].end - pp[i].arrive) / pp[i].serve;
	}
	printf("平均周转周期: %f\t平均带权周转时间: %f\n\n", avert / process, avertt / process);
}

void RR1() {
	pNode* front = (pNode*)malloc(sizeof(pNode));
	pNode* rear = (pNode*)malloc(sizeof(pNode));
	rear = front;
	rear->next = NULL;
	int time = 0;		/*时间参数*/
	float avert = 0, avertt = 0;		/*平均周转,平均带权周转*/
	for (int i = 0; i < process; i++) {		/*计算需要时间长度方便结束循环*/
		time += pp[i].serve;
	}
	printf("RR1(新来进程优先):\n进程\n完成时间区间\t周转时间\t带权周转周期\t\n");
	int length = 0;		/*链表长度*/
	int nowtime = 0;	/*实际运行时间*/
	for (int i = 0; i < process; i++) {
		if (pp[i].arrive == 0) {
			pNode* p;
			p = &pp[i];
			p->use = 0;
			p->next = NULL;
			rear->next = p;
			rear = p;
			length++;
			//printf("%c: %d %d %d %d\n", p->name, p->arrive, p->end, p->serve, p->use);
		}
	}
	while (true) {
		for (int i = 0; i < process; i++) {
			if (pp[i].arrive-1  == nowtime) {
				pNode* p;
				p = &pp[i];
				p->use = 0;
				p->next = NULL;
				rear->next = p;
				rear = p;
				length++;
				//printf("%c: %d %d %d %d\n", p->name, p->arrive, p->end, p->serve, p->use);
			}
		}
		front->next->use++;
		if (length == 1) {
			if (front->next->use == front->next->serve) {
				front->next->end = nowtime + 1;
				rear = front;
				rear->next = NULL;
				length = 0;
				break;
			}
		}
		else {
			if (front->next->use == front->next->serve) {
				front->next->end = nowtime + 1;
				front->next = front->next->next;
				length--;
			}
			else {
				rear->next = front->next;
				front->next = front->next->next;
				rear = rear->next;
				rear->next = NULL;
			}
		}
		nowtime++;
	}
	for (int i = 0; i < process; i++) {
		printf("%c\t%d-%d\t\t%d\t\t%f\n", pp[i].name, pp[i].arrive, pp[i].end, pp[i].end - pp[i].arrive, (float)(pp[i].end - pp[i].arrive) / pp[i].serve);
		avert += pp[i].end - pp[i].arrive; avertt += (float)(pp[i].end - pp[i].arrive) / pp[i].serve;
	}
	printf("平均周转周期: %f\t平均带权周转时间: %f\n\n", avert / process, avertt / process);
}

到了这里,关于操作系统:用C语言实现FCFS(先来先服务),SJF(短作业抢占)和RR(时间片轮转,时间片=1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 操作系统进程调度算法——先来先服务、时间片轮转、优先级调度算法

    (1)算法内容: 先来先服务调度算法是一种最简单的调度算法,可以应用于高级调度也可以运用于低级调度。高级调度时,FCFS调度算法按照作业进入后备作业队列的先后顺序选择作业进入内存,即先进入后备作业队列的作业被优先选择进入内存,然后为选中的作业创建进程

    2023年04月21日
    浏览(44)
  • 操作系统:实验一:进程调度实验——最高优先数优先的调度算法以及先来先服务算法 源码

    一、实验目的 (1)了解进程实体PCB结构; (2)理解进程不同状态和状态之间的转换过程; (3)掌握优先数的调度算法和先来先服务算法; 二、实验内容与要求 设计一个有 N个进程共行的进程调度程序 四、实验步骤 (1)实验设计 进程调度算法: 采用最高优先数优先的调

    2024年02月06日
    浏览(45)
  • 操作系统有关进程调度算法(含先来先服务,短作业优先,优先级调度算法和时间片轮转调度算法)

    本文采用的进程调度算法有:先来先服务,短作业优先,优先级调度算法和时间片轮转调度算法。 针对这四种算法,我采用的是建立数组结构体,如: 先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。采用FCFS算法,每次从

    2024年02月03日
    浏览(61)
  • 【操作系统】磁盘调度算法(FCFS、SSTF、SCAN 和 C-LOOK 调度策略)

    实验内容:硬盘调度 编写一个 C 程序模拟实现课件 Lecture25 中的硬盘磁头调度算法,包括 FCFS、SSTF、SCAN 和 C-LOOK 调度策略。 固定一个硬盘柱面数; 输入一批随机的硬盘柱面请求序列,计算各个调度策略下的磁头移动平均总距离 (假设磁头运动是理想匀速的,可以把移动距离

    2024年02月11日
    浏览(40)
  • 磁盘调度算法之先来先服务(FCFS),最短寻找时间优先(SSTF),扫描算法(SCAN,电梯算法),LOOK调度算法

    寻找时间(寻道时间) Ts:在读/写数据前,将磁头移动到指定磁道所花的时间。 ① 启动磁头臂 是需要时间的。假设耗时为s; ② 移动磁头 也是需要时间的。假设磁头匀速移动,每跨越一个磁道耗时为m,总共需要跨越n条磁道。 则寻道时间 T s = s + m ∗ n Ts =s + m*n T s = s + m ∗

    2024年02月08日
    浏览(47)
  • 银河麒麟服务器操作系统修改系统默认语言(如从英文改为中文)

    在安装操作系统的时候选择了英文,使用的时候感觉不太方便,想要把语言环境改成中文; 银河麒麟高级服务器操作系统V10 SP3 1、查看系统默认语言 2、使用localectl命令设定系统语言为中文 3、重启系统

    2024年02月04日
    浏览(77)
  • 操作系统动态内存分配算法【C语言实现】

    题目: 采用五个算法,各自作业在1024kB空间上分配情况。 内存可变分区分配仿真算法 :首次适应,下次适应,最佳适应,最坏适应和快速分配。 使用的结构体数组表示起始地址,内存块大小,内存块状态(0空闲,1占用) void bubbleprint(struct Info info[]) 函数是为了内存块大小

    2024年02月03日
    浏览(44)
  • 操作系统进程调度算法(c语言模拟实现)

            前言: 本文旨在分享如何使用c语言对操作系统中的部分进程调度算法进行模拟实现,以及算法描述的讲解, 完整代码放在文章末尾,欢迎大家自行拷贝调用 目录 常见的调度算法 数据结构 先来先服务调度算法 算法模拟思路: 算法模拟:  最短作业优先调度算法

    2024年02月06日
    浏览(55)
  • 操作系统进程调度算法的模拟实现(c语言版本)

            前言: 本文旨在分享如何使用c语言对操作系统中的部分进程调度算法进行模拟实现,以及算法描述的讲解, 完整代码放在文章末尾,欢迎大家自行拷贝调用 目录 常见的调度算法 数据结构 先来先服务调度算法 算法模拟思路: 算法模拟:  最短作业优先调度算法

    2024年02月06日
    浏览(55)
  • 【操作系统】FIFO先进先出页面置换算法(C语言实现)

    FIFO页面置换算法,计算缺页率,文末附代码,及例题解析 1、内容         在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选择一个页面将其移出内存,以便为

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包