先来先服务算法、运行时间最短者优先算法和最高响应比优先调度算法_CPU的调度器scheduler...

处理器调度器是操作系统的关键组件,负责分配CPU资源。本文深入探讨了低级调度器,包括非抢占式(FCFS、SJF、优先级)和抢占式(SRTF、RR)调度算法,以及Linux 2.6.x版本的调度框架,旨在平衡效率、交互性和避免饥饿。
摘要由CSDN通过智能技术生成

处理器作为计算机系统里的一种资源,也是需要管理,从而调度分配给需要的程序以达到最高效率,所以调度器应运而生。

1. 调度器overview

调度器本身也是一个程序,目的是为了给执行用户的程序提供资源,包含了一个决定一组程序中谁会赢得CPU时钟周期的算法。

664ad7949a9b93de4b971252fef13a16.png

在桌面机,嵌入式设备或大型机等不同的环境中,产生了不同的调度器。我们一般针对不同层面,分为下面几种调度器:

  1. 高级调度器(long-term scheduler): 通常用于面向批处理的多程序环境中,通过均衡内存中的任务以欧化系统资源,包括CPU,内存和硬盘存储等。
  2. 中级调度器(medium-term scheduler):跟踪CPU上执行的进程的动态内存用量来决定是否要增加或减少“多通道程度“(内存中竞争CPU的进程个数),以防止”颠簸“。颠簸即当前的进程集合的内存需求超过了系统容量,导致进程在各自的执行中变得缓慢。
  3. 低级调度器(short-term scheduler):负责在当前驻留的内存里的进程中选择一个来运行。这篇内容设计的算法主要关注的都是低级调度器。

2. 调度的步骤

在低级调度器中,一般划分为:非抢占式抢占式。非抢占式的调度器中,一个进程要不然就一直执行到底,要不然就自己主动资源放弃处理器,以处理I/O请求,调度器只是安排先后顺序;而抢占式调度器里,调度器从当前进程手中把处理器抢走,交给另一个进程,有这么一个主动的动作。不管是哪一种,调度器的执行步骤一般如下:

  1. 获得处理器的控制权
  2. 把当前正在运行的进程状态(PCB,process control block)保存下来
  3. 选择一个新的进程来执行
  4. 把新选择出来的进程分发给处理器运行,这一步会把第二步中的状态再加载到CPU寄存器中。

可以看出,在调度器调度过程中,进程状态很重要,它包括了很多信息:程序执行到哪儿了(PC指针)以便回来继续执行,程序

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以提供一些思路和伪代码供你参考。 首先,需要定义磁盘调度算法的数据结构,包括磁盘请求队列、当前磁头位置和寻道方向等信息。然后,可以根据不同的算法实现相应的调度函数。 以下是伪代码示例: ```c // 定义磁盘请求结构体 typedef struct { int track; // 磁道号 int time; // 提交时间 } Request; // 定义磁盘调度算法结构体 typedef struct { Request queue[MAX_REQUESTS]; // 磁盘请求队列 int head; // 当前磁头位置 int direction; // 寻道方向,1表示向外,-1表示向内 int count; // 请求计数 double total_distance; // 总寻道距离 } Scheduler; // 先来先服务算法 void fcfs(Scheduler* scheduler, Request request) { // 将请求加入队列尾部 scheduler->queue[scheduler->count++] = request; // 计算寻道距离 int distance = abs(request.track - scheduler->head); scheduler->total_distance += distance; // 更新磁头位置 scheduler->head = request.track; } // 最短寻道时间优先算法 void sstf(Scheduler* scheduler, Request request) { // 将请求加入队列尾部 scheduler->queue[scheduler->count++] = request; // 找到距离最近的请求 int min_distance = INT_MAX; int min_index = -1; for (int i = 0; i < scheduler->count; i++) { int distance = abs(scheduler->queue[i].track - scheduler->head); if (distance < min_distance) { min_distance = distance; min_index = i; } } // 计算寻道距离 scheduler->total_distance += min_distance; // 更新磁头位置 scheduler->head = scheduler->queue[min_index].track; // 将请求移到队列头部 Request temp = scheduler->queue[min_index]; for (int i = min_index; i > 0; i--) { scheduler->queue[i] = scheduler->queue[i - 1]; } scheduler->queue[0] = temp; } // 扫描算法 void scan(Scheduler* scheduler, Request request) { // 将请求加入队列尾部 scheduler->queue[scheduler->count++] = request; // 排序请求队列 for (int i = 0; i < scheduler->count - 1; i++) { for (int j = i + 1; j < scheduler->count; j++) { if (scheduler->queue[i].track > scheduler->queue[j].track) { Request temp = scheduler->queue[i]; scheduler->queue[i] = scheduler->queue[j]; scheduler->queue[j] = temp; } } } // 计算寻道距离 int distance = 0; int index = 0; while (index < scheduler->count && scheduler->queue[index].track < scheduler->head) { distance += abs(scheduler->queue[index].track - scheduler->head); scheduler->head = scheduler->queue[index].track; index++; } if (index < scheduler->count && scheduler->queue[index].track == scheduler->head) { index++; } while (index < scheduler->count) { distance += abs(scheduler->queue[index].track - scheduler->head); scheduler->head = scheduler->queue[index].track; index++; } scheduler->total_distance += distance; } // 循环扫描算法 void cscan(Scheduler* scheduler, Request request) { // 将请求加入队列尾部 scheduler->queue[scheduler->count++] = request; // 排序请求队列 for (int i = 0; i < scheduler->count - 1; i++) { for (int j = i + 1; j < scheduler->count; j++) { if (scheduler->queue[i].track > scheduler->queue[j].track) { Request temp = scheduler->queue[i]; scheduler->queue[i] = scheduler->queue[j]; scheduler->queue[j] = temp; } } } // 计算寻道距离 int distance = 0; int index = 0; while (index < scheduler->count && scheduler->queue[index].track < scheduler->head) { distance += abs(scheduler->queue[index].track - scheduler->head); scheduler->head = scheduler->queue[index].track; index++; } if (index < scheduler->count && scheduler->queue[index].track == scheduler->head) { index++; } if (index == scheduler->count) { // 如果已经扫描到队列末尾 distance += abs(scheduler->queue[0].track - scheduler->head); scheduler->head = scheduler->queue[0].track; index = 0; } while (index < scheduler->count) { distance += abs(scheduler->queue[index].track - scheduler->head); scheduler->head = scheduler->queue[index].track; index++; } scheduler->total_distance += distance; } // 计算平均寻道长度 double average_distance(Scheduler* scheduler) { return scheduler->total_distance / scheduler->count; } // 主函数 int main() { Scheduler scheduler; scheduler.head = 50; // 假设初始磁头位置为50 scheduler.direction = 1; // 假设初始寻道方向向外 scheduler.count = 0; scheduler.total_distance = 0.0; // 读取磁盘请求,调用相应的调度算法 while (has_request()) { Request request = read_request(); if (scheduler.direction == 1) { if (request.track >= scheduler.head) { fcfs(&scheduler, request); } else { scheduler.direction = -1; scan(&scheduler, request); } } else { if (request.track <= scheduler.head) { fcfs(&scheduler, request); } else { scheduler.direction = 1; cscan(&scheduler, request); } } } // 输出平均寻道长度 printf("FCFS: %lf\n", average_distance(&scheduler)); // 重新初始化调度算法结构体 scheduler.head = 50; scheduler.direction = 1; scheduler.count = 0; scheduler.total_distance = 0.0; // 读取磁盘请求,调用相应的调度算法 while (has_request()) { Request request = read_request(); sstf(&scheduler, request); } // 输出平均寻道长度 printf("SSTF: %lf\n", average_distance(&scheduler)); // 重新初始化调度算法结构体 scheduler.head = 50; scheduler.direction = 1; scheduler.count = 0; scheduler.total_distance = 0.0; // 读取磁盘请求,调用相应的调度算法 while (has_request()) { Request request = read_request(); scan(&scheduler, request); } // 输出平均寻道长度 printf("SCAN: %lf\n", average_distance(&scheduler)); // 重新初始化调度算法结构体 scheduler.head = 50; scheduler.direction = 1; scheduler.count = 0; scheduler.total_distance = 0.0; // 读取磁盘请求,调用相应的调度算法 while (has_request()) { Request request = read_request(); cscan(&scheduler, request); } // 输出平均寻道长度 printf("CSCAN: %lf\n", average_distance(&scheduler)); return 0; } ``` 需要注意的是,以上代码仅为伪代码示例,实际实现中需要考虑更多细节和异常情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值