时间片轮转(RR)调度算法(详解版)

时间片轮转(RR)调度算法主要用于分时系统,通过设置时间片来轮流执行进程。每个进程最多获得一个时间片的CPU执行,超过时间片则被抢占并重新加入就绪队列。算法性能受时间片大小影响,过大接近FCFS,过小则引起过多上下文切换。平均等待时间和周转时间与时间片大小有关,需权衡上下文切换成本和进程切换频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章来源:http://c.biancheng.net/view/1247.html

时间片轮转(RR)调度算法是专门为分时系统设计的。它类似于 FCFS调度,但是增加了抢占以切换进程。
该算法中,将一个较小时间单元定义为时间量时间片。时间片的大小通常为 10~100ms。就绪队列作为循环队列。CPU 调度程序循环整个就绪队列,为每个进程分配不超过一个时间片的 CPU。

为了实现 RR 调度,我们再次将就绪队列视为进程的 FIFO 队列。新进程添加到就绪队列的尾部。CPU 调度程序从就绪队列中选择第一个进程,将定时器设置在一个时间片后中断,最后分派这个进程。

接下来,有两种情况可能发生。进程可能只需少于时间片的 CPU 执行。对于这种情况,进程本身会自动释放 CPU。调度程序接着处理就绪队列的下一个进程。否则,如果当前运行进程的 CPU 执行大于一个时间片,那么定时器会中断,进而中断操作系统。然后,进行上下文切换,再将进程加到就绪队列的尾部,接着 CPU 调度程序会选择就绪队列内的下一个进程。

不过,采用 RR 策略的平均等待时间通常较长。假设有如下一组进程,它们在时间 0 到达,其 CPU 执行以 ms 计:
请添加图片描述
如果使用 4ms 的时间片,那么 P1 会执行最初的 4ms。由于它还需要 20ms,所以在第一个时间片之后它会被抢占,而 CPU 就交给队列中的下一个进程。由于 P2 不需要 4ms,所以在其时间片用完之前就会退出。CPU 接着交给下一个进程,即进程 P3。在每个进程都得到了一个时间片之后,CPU 又交给了进程 P1 以便继续执行。因此,RR 调度结果如下:
请添加图片描述
现在,我们计算这个调度的平均等待时间。P1 等待 10-4 = 6ms,P2 等待 4ms,而 P3 等待 7ms。因此,平均等待时间为17/3 = 5.66ms。
在 RR 调度算法中,没有进程被连续分配超过一个时间片的 CPU(除非它是唯一可运行的进程)。如果进程的 CPU 执行超过一个时间片,那么该进程会被抢占,并被放回到就绪队列。因此,RR调度算法是抢占的
如果就绪队列有 n 个进程,并且时间片为 q,那么每个进程会得到 1/n 的 CPU 时间,而且每次分得的时间不超过 q 个时间单元。每个进程等待获得下一个 CPU 时间片的时间不会超过 (n-1)q 个时间单元。例如,如果有 5 个进程,并且时间片为 20ms,那么每个进程每 100ms 会得到不超过 20ms 的时间。
RR 算法的性能很大程度取决于时间片的大小。在一种极端情况下,如果时间片很大,那么 RR 算法与 FCFS 算法一样。相反,如果时间片很小(如 1ms),那么 RR 算法可以导致大量的上下文切换。

例如,假设我们只有一个需要 10 个时间单元的进程。如果时间片为 12 个时间单元,那么进程在一个时间片不到就能完成,而且没有额外开销。如果时间片为 6 个时间单元,那么进程需要 2 个时间片,并且还有一个上下文切换。如果时间片为 1 个时间单元,那么就会有 9 个上下文切换,相应地使进程执行更慢(图 1)。
请添加图片描述
因此,我们希望时间片远大于上下文切换时间。如果上下文切换时间约为时间片的 10%,那么约 10% 的 CPU 时间会浪费在上下文切换上。在实践中,大多数现代操作系统的时间片为 10~100ms,上下文切换的时间一般少于 10ms;因此,上下文切换的时间仅占时间片的一小部分。

周转时间也依赖于时间片大小。正如从图 2 中所看到的,随着时间片大小的增加,一组进程的平均周转时间不一定会改善。一般情况下,如果大多数进程能在一个时间片内完成,那么平均周转时间会改善。
请添加图片描述
例如,假设有三个进程,都需要 10 个时间单元。如果时间片为 1 个时间单元,那么平均周转时间为 29;如果时间片为 10,那么平均周转时间会降为 20;如果再考虑上下文切换时间,那么平均周转时间对于较小时间片会增加,这是因为需要更多的上下文切换。

尽管时间片应该比上下文切换时间要大,但也不能太大。如果时间片太大,那么 RR 调度就演变成了 FCFS 调度。根据经验,80% 的 CPU 执行应该小于时间片。

### RR调度算法概述 RR(Round Robin,旋转调度算法是一种基于时间片的CPU调度方法。其核心思想是将CPU时间划分为一系列固定长度的时间片段,称为时间片。每个就绪状态的进程依次获得一个时间片用于运行[^1]。 一旦某个进程的时间片耗尽而尚未完成任务,则该进程会被移至就绪队列的末尾,并等待下一轮调度。通过这种方式,RR算法能够确保所有进程公平地共享CPU资源,从而避免某些进程长期占用CPU的情况发生。 --- ### 时间片的选择 时间片的大小对于RR算法的表现至关重要。如果时间片过长,RR算法的行为会接近于先来先服务(FCFS)调度;反之,若时间片过短,则可能导致过多的上下文切换开销,降低系统的整体性能[^2]。 通常情况下,合理的时间片应介于平均I/O请求间隔和平均计算时间之间,具体数值需依据实际应用场景调整。 --- ### RR调度算法的实现方式 以下是RR调度算法的一种典型实现: #### 数据结构设计 - **就绪队列**:采用先进先出(FIFO)队列存储待处理的进程。 - **时间片计数器**:记录当前进程已使用的CPU时间。 #### 关键逻辑描述 1. 初始化就绪队列并设置全局时间片参数 `time_slice`。 2. 当前进程中断或时间片到期时,保存其状态并将控制权交还给调度程序。 3. 如果进程未完成,将其重新加入到就绪队列的末尾。 4. 调度下一个处于就绪队列头部的进程继续执行。 #### Python代码示例 以下是一个简单的RR调度模拟实现: ```python class Process: def __init__(self, pid, burst_time): self.pid = pid # 进程ID self.burst_time = burst_time # 需要的总CPU时间 self.remaining_time = burst_time # 剩余CPU时间 def round_robin(processes, time_slice): n = len(processes) current_time = 0 queue = processes[:] # 就绪队列初始化 while True: all_done = True for i in range(n): if queue[i].remaining_time > 0: all_done = False if queue[i].remaining_time > time_slice: current_time += time_slice queue[i].remaining_time -= time_slice else: current_time += queue[i].remaining_time queue[i].remaining_time = 0 print(f"Process {queue[i].pid} completed at time {current_time}") if all_done: break # 测试数据 process_list = [ Process(1, 10), Process(2, 5), Process(3, 7) ] round_robin(process_list, 2) # 设置时间片为2单位时间 ``` 上述代码定义了一个基本的RR调度模型,其中每个进程按照设定的时间片逐步消耗其所需的CPU时间。 --- ### 性能特点分析 RR算法的主要优点在于其简单性和公平性。由于每个进程都按顺序分配固定的CPU时间,因此不会出现饥饿现象。然而,在高负载环境下,频繁的上下文切换可能会增加额外的系统开销。 此外,RR算法并不考虑不同进程的实际需求差异,这可能使得较轻量的任务无法快速得到响应,进而影响用户体验。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值