CPU调度算法-Linux操作系统下的时间片轮转调度算法-C语言(附代码)

本文详细介绍了时间片轮转调度算法的工作原理,如何保证公平性,以及其在处理大量短任务时的效率。并通过C语言代码实例展示了该算法的实现过程。时间片长度的选择对系统性能至关重要,适用于分时系统。
摘要由CSDN通过智能技术生成

想象一下你在一家餐厅里,服务员是CPU,而顾客则是需要服务的进程。这家餐厅有一个规则:每个顾客只能得到固定时间的服务,比如说2分钟。这就是“时间片”。

  1. 顾客到达:顾客(进程)按到达的时间顺序排队等待服务。
  2. 服务时间:服务员(CPU)开始服务第一个顾客。如果这个顾客在2分钟内吃完了(进程完成了任务),他就会离开。
  3. 时间片结束:如果2分钟结束了,但顾客还没吃完,服务员会让他回到队伍的末尾,等待下一轮服务。
  4. 轮转服务:服务员接着服务下一个顾客,以此类推。

这样,每个顾客都能得到公平的服务时间,没有人会饿着。但如果顾客太多,或者每个人的饭量不一样(进程的任务大小不同),就需要合理安排每个人的服务时间(时间片的长度),以确保大家都满意。

这就是时间片轮转调度算法的通俗解释。它确保了每个进程都有机会执行,而且系统能高效地处理大量短任务。

时间片轮转调度算法(Round-Robin Scheduling, 简称RR)是一种公平且简单的进程调度方式,特别适用于分时系统。这个算法的核心思想是将所有的就绪进程排成一个队列,并给每个进程分配一个固定的时间段,称为“时间片”(time slice),通常在10到100毫秒之间。每个进程轮流使用CPU一段时间,即一个时间片。如果进程在其时间片结束前完成或阻塞,CPU会立即切换到下一个进程。如果进程没有在时间片结束前完成,它会被移到就绪队列的末尾,等待下一次被调度。

在时间片轮转调度中,进程的切换可以发生在两种情况下:

  1. 如果一个进程在时间片结束前已经完成任务,它会被从就绪队列中移除,CPU会分配给下一个进程。
  2. 如果时间片结束时进程还未完成,它会被放到就绪队列的末尾,等待下一轮的调度。

时间片的长度对系统性能有重要影响。如果时间片设置得太短,会导致频繁的进程切换,增加系统开销;如果设置得太长,则会降低系统对短交互请求的响应速度。因此,时间片的长度通常需要根据系统的具体需求来平衡设置。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MAX_PROCESSES 10
#define TIME_SLICE 2
// 进程数据结构
typedef struct {
	int pid; // 进程 ID
	int arrival; // 到达时间
	int service; // 服务时间
	int remaining; // 剩余服务时间
} Process;
// 初始化进程数组
void initializeProcesses(Process processes[], int n) {
	printf("Enter arrival time and service time for each process:\n");
	int i;
	for (i = 0; i < n; i++) {
		printf("Process %d: ", i + 1);
		scanf("%d %d", &processes[i].arrival, &processes[i].service);
		processes[i].pid = i + 1;
		processes[i].remaining = processes[i].service;
	}
}

// 时间片轮转调度算法
void roundRobin(Process processes[], int n) {
	int currentTime = 0;
	int completed = 0;
	while (completed < n) {
		int i;
		for (i = 0; i < n; i++) {
			if (processes[i].remaining > 0) {
			// 执行当前进程
				printf("Time %d: Executing process %d\n", currentTime,processes[i].pid);
				if (processes[i].remaining > TIME_SLICE) {
					currentTime += TIME_SLICE;
					processes[i].remaining -= TIME_SLICE;
				} else {
					currentTime += processes[i].remaining;
					processes[i].remaining = 0;
					completed++;
				}
			}
		}
	}
}

int main() {
	Process processes[MAX_PROCESSES];
	int n;
	// 输入进程数量和每个进程的信息
	printf("Enter the number of processes: ");
	scanf("%d", &n);
	// 初始化进程数组
	initializeProcesses(processes, n);
	// 执行时间片轮转调度算法
	roundRobin(processes, n);
	return 0;
}

这段代码是一个简单的时间片轮转调度算法的实现。下面是代码的主要部分和它们的功能:

  1. 进程结构体(Process)

    • pid:进程ID。
    • arrival:进程到达时间。
    • service:进程服务时间(即需要的CPU时间)。
    • remaining:进程剩余服务时间。
  2. 初始化进程(initializeProcesses函数)

    • 这个函数用于初始化进程数组。它会询问用户输入每个进程的到达时间和服务时间,并将这些信息存储在进程数组中。
  3. 时间片轮转调度(roundRobin函数)

    • 这个函数实现了时间片轮转调度算法。它使用一个while循环来持续检查是否所有进程都已完成。
    • 对于每个进程,如果它的remaining(剩余服务时间)大于0,表示它还需要CPU时间。
    • 如果进程的剩余时间大于时间片(TIME_SLICE),它会执行一个时间片的长度,并更新currentTimeremaining
    • 如果进程的剩余时间小于或等于时间片,它会完成剩余的服务时间,currentTime会增加相应的时间,remaining设置为0,completed增加1。
  4. 主函数(main)

    • 主函数首先定义了一个进程数组processes,大小为MAX_PROCESSES
    • 然后,它会询问用户输入进程的数量,并调用initializeProcesses函数来初始化进程。
    • 最后,它调用roundRobin函数来执行时间片轮转调度算法。

这段代码的关键点在于它如何模拟进程在时间片轮转调度中的行为。每个进程轮流使用CPU,如果在分配的时间片内没有完成,则会被放回队列末尾,等待下一次机会。这样可以确保所有进程都有公平的机会使用CPU资源。代码中的TIME_SLICE宏定义了每个时间片的长度,而MAX_PROCESSES宏定义了可以处理的最大进程数。这两个值可以根据需要进行调整。

要使用这个程序,您需要按照以下步骤操作:

  1. 编译代码:首先,您需要使用C语言编译器编译这段代码。如果您使用的是GCC编译器,可以在命令行中输入以下命令:

gcc -o roundRobin roundRobin.c

        这里roundRobin.c是您保存代码的文件名,roundRobin是编译后生成的可执行文件名。

     2. 运行程序:编译成功后,您可以运行这个程序。在命令行中输入以下命令:

./roundRobin

        程序会提示您输入进程的数量和每个进程的到达时间及服务时间。

    3. 输入数据:按照提示输入进程的数量(不超过10个),然后为每个进程输入到达时间和服务时间。

    4. 查看结果:输入完数据后,程序会根据您输入的数据执行时间片轮转调度算法,并显示每个时间片执行的进程和时间。

下面是一个使用示例及其结果:

Enter the number of processes: 3
Enter arrival time and service time for each process:
Process 1: 0 5
Process 2: 1 3
Process 3: 2 4
Time 0: Executing process 1
Time 2: Executing process 1
Time 4: Executing process 2
Time 6: Executing process 2
Time 8: Executing process 3
Time 10: Executing process 3
Time 12: Executing process 1
Time 14: Executing process 1
Time 16: Executing process 2
Time 18: Executing process 3
Time 20: Executing process 3
Time 22: Executing process 1

在这个示例中,我们有3个进程,它们的到达时间和服务时间分别是:

  • 进程1:到达时间0,服务时间5。
  • 进程2:到达时间1,服务时间3。
  • 进程3:到达时间2,服务时间4。

时间片长度设置为2。程序按照时间片轮转调度算法执行,每个进程轮流使用CPU时间片。从结果中可以看出,每个进程都按顺序执行,直到所有进程的服务时间都用完。

请注意,实际使用时,您需要根据实际情况输入进程的数据。

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一段使用C语言编写的时间片轮转法调度算法的伪代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义进程结构体 typedef struct Process { char name[10]; // 进程名 int arrival_time; // 到达时间 int burst_time; // 执行时间 int remaining_time; // 剩余执行时间 int turnaround_time;// 周转时间 int waiting_time; // 等待时间 int finish_time; // 完成时间 int started; // 标记是否已经开始运行 } Process; // 时间片轮转法调度算法 void rr_scheduling(Process *processes, int n, int time_quantum) { int time = 0; // 当前时间 int i, j, k, flag, total_time; Process *current_process; // 当前正在运行的进程 Process *next_process; // 下一个要运行的进程 int *finished = (int *)malloc(n * sizeof(int)); // 标记进程是否已经完成 memset(finished, 0, n * sizeof(int)); total_time = 0; while (1) { flag = 0; // 标记是否有进程正在运行 for (i = 0; i < n; i++) { if (processes[i].arrival_time <= time && !finished[i]) { if (!processes[i].started) { processes[i].started = 1; processes[i].waiting_time = time - processes[i].arrival_time; } current_process = &processes[i]; flag = 1; break; } } if (!flag) { // 所有进程都已完成 break; } if (current_process->remaining_time <= time_quantum) { // 进程执行完毕 next_process = NULL; current_process->remaining_time = 0; current_process->finish_time = time + current_process->remaining_time; current_process->turnaround_time = current_process->finish_time - current_process->arrival_time; finished[i] = 1; total_time += current_process->turnaround_time; } else { // 进程还没有执行完毕 next_process = current_process; next_process->remaining_time -= time_quantum; } for (j = time; j < time + time_quantum; j++) { flag = 0; for (k = 0; k < n; k++) { if (processes[k].arrival_time <= j && !finished[k]) { flag = 1; break; } } if (!flag) { // 所有进程都已完成 break; } } time = j; if (next_process != NULL) { // 把进程放到队列的末尾 processes[n] = *next_process; n++; } } printf("Average Turnaround Time: %.2f\n", (float)total_time / n); free(finished); } int main() { int n, i, time_quantum; Process *processes; printf("Enter the number of processes: "); scanf("%d", &n); processes = (Process *)malloc(n * sizeof(Process)); for (i = 0; i < n; i++) { printf("Enter the name, arrival time and burst time of process %d: ", i + 1); scanf("%s %d %d", processes[i].name, &processes[i].arrival_time, &processes[i].burst_time); processes[i].remaining_time = processes[i].burst_time; processes[i].started = 0; } printf("Enter the time quantum: "); scanf("%d", &time_quantum); rr_scheduling(processes, n, time_quantum); free(processes); return 0; } ``` 这段代码实现了一个简单的时间片轮转法调度算法,用于调度进程的执行顺序。它会根据每个进程的到达时间和执行时间进行调度,以最小化平均周转时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值