常用调度算法

先来先服务(FCFS)

先来先服务(FCFS, First Come First Serve)是最简单的调度算法,按先后顺序进行调度。

FCFS算法

按照作业提交或进程变为就绪状态的先后次序,分派CPU; 当前作业或进程占用CPU,直到执行完或阻塞,才出让CPU(非抢占方式)。 在作业或进程唤醒后(如I/O完成),并不立即恢复执行,通常等到当前作业或进程出让CPU。最简单的算法。

FCFS的特点

比较有利于长作业,而不利于短作业。 有利于CPU繁忙的作业,而不利于I/O繁忙的作业。

轮转法(Round Robin)

轮转法(Round Robin)是让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。

轮转法

将系统中所有的就绪进程按照FCFS原则,排成一个队列。
每次调度时将CPU分派给队首进程,让其执行一个时间片。时间片的长度从几个ms到几百ms。
在一个时间片结束时,发生时钟中断。
调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程。? 进程可以未使用完一个时间片,就出让CPU(如阻塞)。

最短作业优先算法SJF
SJF(Shortest Job First )

时间片长度的确定

时间片长度变化的影响2 过长->退化为FCFS算法,进程在一个时间片内都执行完,响应时间长。2 过短->用户的一次请求需要多个时间片才能处理完,上下文切换次数增加,响应时间长。
对响应时间的要求:T(响应时间)=N(进程数目)*q(时间片)
就绪进程的数目:数目越多,时间片越小
系统的处理能力:应当使用户输入通常在一个时间片内能处理完,否则使响应时间,平均周转时间和平均带权周转时间延长。

最短作业优先(SJF)

SJF(Shortest Job First )
按照CPU阵发时间递增的次序调度,易于证明其平均周转时间最短
优点:最大限度地降低了平均等待时间

缺点:不公平;容易产生饥饿,甚至饿死

最短剩余时间优先算法(SRTN)

shortest remaining time next
(剥夺式算法)当CPU空闲时,选择剩余时间最短的进程或者线程。当一个新进程或线程到达时,比较新进程所需时间与当前运行进程的估计剩余时间。如果新进程所需的运行时间短,则切换运行进程。

最高响应比优先算法(HRN):

(HRN,Highest Response_ratio Next)

对于同时到达的任务处理时间较短的任务将被优先调度,处理时间较长的任务将随着时间的增加而动态提升响应比,因而不会出现饥饿现象。
在这里插入图片描述

最高优先数优先算法(HPF)

当需要进行处理器分配时,系统在可运行的进程中选择优先数最高者使其投入运行。

   赋予优先数的方法:

   ①静态优先数:进程进入系统时被赋予,在生命周期内固定不变。适合批处理进程

                 优点:较简单;开销较小

                 缺点:公平性差,可能会造成低优先数进程长期等待。

   ②动态优先数:进程在创建时被赋予,在生命周期内动态变化。

                 优点:资源利用率高,公平性好

                 缺点:开销较大;实现较复杂

循环轮转算法(RR)

系统为每一个进程规定一个时间片,所有进程按照其时间片的长短轮流地进行。适用于分时系统,公平;响应及时。

   ①基本轮转

   ②改进轮转

分类排队算法(MLQ)

以多个就绪进程队列为特征的,这些队列将系统中所有可运行的进程按照某种原则加以分类,以实现所期望的调度目标。

反馈算法(FB)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了你的要求。首先,我需要确认一下你的问题是:如何在Linux环境下使用C/C++语言编写程序模拟实现最近最不常用调度算法LFU是吗? 如果我的理解是正确的,那么我可以给你提供一些思路和参考代码。同时,由于我是一个语言模型,并没有能力生成程序框图,但是我可以为你提供一份程序的伪代码,你可以根据这份伪代码自己画出框图。 首先,我们需要了解一下LFU算法的原理。LFU是Least Frequently Used的缩写,即最近最不常用页面置换算法。它的基本思想是根据页面的历史访问次数来进行页面置换,即选择访问次数最少的页面进行置换。LFU算法适合处理那些访问次数比较稳定的数据。 接下来,我们就可以根据这个算法来编写程序了。下面是一个简单的伪代码示例: ```c++ #include <iostream> #include <unordered_map> #include <list> using namespace std; class LFUCache { public: LFUCache(int capacity) { this->capacity = capacity; minFreq = 0; } int get(int key) { if (cache.find(key) == cache.end()) { return -1; } auto node = cache[key]; freq[node->freq].erase(node); if (freq[node->freq].size() == 0) { freq.erase(node->freq); if (minFreq == node->freq) { minFreq++; } } node->freq++; freq[node->freq].push_front(node); return node->value; } void put(int key, int value) { if (capacity <= 0) { return; } if (cache.find(key) != cache.end()) { auto node = cache[key]; freq[node->freq].erase(node); if (freq[node->freq].size() == 0) { freq.erase(node->freq); if (minFreq == node->freq) { minFreq++; } } node->freq++; node->value = value; freq[node->freq].push_front(node); } else { if (cache.size() >= capacity) { auto node = freq[minFreq].back(); cache.erase(node->key); freq[minFreq].pop_back(); if (freq[minFreq].size() == 0) { freq.erase(minFreq); } } auto node = new Node(key, value); cache[key] = node; freq[1].push_front(node); minFreq = 1; } } private: struct Node { int key; int value; int freq; Node(int k, int v) : key(k), value(v), freq(1) {} }; int capacity; int minFreq; unordered_map<int, list<Node*>::iterator> cache; unordered_map<int, list<Node>> freq; }; ``` 这个伪代码实现了一个LFU缓存,其中LFUCache类用于封装缓存的操作,Node结构体用于表示缓存中的节点,cache哈希表用于存储节点,freq哈希表用于存储不同访问次数的节点列表。 在get方法中,首先判断要获取的节点是否存在,如果不存在则返回-1;如果存在,则将节点从原来的访问次数列表中删除,如果原来的访问次数列表为空,则从freq哈希表中删除该访问次数,如果该访问次数等于最小访问次数,则将最小访问次数加1。然后将该节点的访问次数加1,并将其插入到访问次数为新访问次数的列表头部,最后返回节点的值。 在put方法中,首先判断缓存中是否已经存在该节点,如果存在,则将其从原来的访问次数列表中删除,如果原来的访问次数列表为空,则从freq哈希表中删除该访问次数,如果该访问次数等于最小访问次数,则将最小访问次数加1。然后将该节点的访问次数加1,并更新节点的值,然后将其插入到访问次数为新访问次数的列表头部。如果缓存已满,则找到访问次数最小的节点进行删除,最后将新节点插入到缓存中。 这就是一个简单的LFU缓存实现,你可以根据这个伪代码来编写你的程序,同时根据伪代码来画出程序的框图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值