Zephyr维护了一个就绪队列和多个内核对象等待队列。所有就绪线程被放入就绪队列等待调度器来选择线程进入调度,等待信号量,互斥量等其它内核对象的线程,会分别放到对应内核对象的等待队列中,当等待的资源就绪时,将从对应的队列中选出线程使用资源。

在Zephyr运行过程中,根据运行的情况任意一个队列中都可能存在多个线程,随时都会有线程会从队列中加入,取出。这些对队列的操作需要满足选择出优先级最高且等待最久的线程,Zephyr中提供三种算法用于管理队列,不同的工作环境可以通过配置Zephyr选择不同的算法管理不同的队列。

队列管理算法

Zephyr提供三种队列管理算法管理列队,不同的的队列管理算法适用于不同的场景,Zephyr队列管理算法在一开始就配置好后通过编译的方式固定下来,运行过程中是无法修改的。任何队列的管理算法都提供“插入”,“查询”,“删除”三种操作。

多链表队列

多链表队列是由一个数组加多个链表组成,每个数组元素指向一个链表,每个链表内保存相同优先级的线程。多链表队列在代码量上和单链表队列相差无几,但会多使用内存。为了控制内存的用量, Zephyr限制在多链表队列下只允许线程32个优先级。多链表列队在插入,查询,删除的算法都是一致的,第一步先在数组中定位线程所在的链表,再操作链表。多链表列队的数据结构如下:

1
2
3
4
struct _priq_mq {sys_dlist_t queues[32];unsigned int bitmask; /* bit 1<<i set if queues[i] is non-empty */
};

queues对应32个优先级的链表,bitmask中以bit的位置标识有哪些优先级上有线程在链表中,Zephyr中配置了最高优先级K_HIGHEST_THREAD_PRIO,假设要定位优先级为prio所在的链表是queues[prio-K_HIGHEST_THREAD_PRIO],Zephyr中优先级越高其数字越低,所以这里会用减。

对多链表列队进行插入时,会先通过插入线程的优先级定位到线程链表,再将线程插入到链表末尾,其插入算法的时间复杂度为O(1):

对多链表列队进行查询时,先计算bitmask低位的连续0数量,该数量就是最高优先级在多链表数组中的下标,通过下标取得最高优先级所在链表,其链表的头节点就是等待最久的线程,直接取出该节点完成查询,可见查询的时间复杂度为O(1):

对多链表列队进行删除时,可能是列队中任何线程,会根据要删除线程的优先级直接找到对应的链表,再从前向后遍历单链表,当遇到指定的线程时将其从链表中移除,如果该优先级链表中只有一个线程,删除的时间复杂度最优为O(1),如果所有的线程都集中在这个优先级上,时间复杂度变为O(n), 因此在使用多链表列队算法时要适当安排线程优先级。

单链表

单链表是用一条双向链表将列队内的所有线程串接起来,单链表列队算法的代码量和占用内存都非常小,在列队内线程较少的情况下O(n)的时间复杂度基本可以忽略,因此存储敏感的系统且列队内只需要管理较少线程的情况下可选用该算法。

对单链表列队进行插入时,会从前向后遍历单链表,当遇到有插入线程优先级级小的线程节点时,将线程插入到该线程节点前,其插入算法的时间复杂度为O(n):

插入到该线程节点前,其插入算法的时间复杂度为O(n):

对单链表列队进行查询时,需要取出优先级最高且等待最久的线程。在插入的时候已经将链表排序,因此直接取出单链表的第一个节点就可以满足该条件,查询的时间复杂度为O(1):

对单链表列队进行删除时,可能是列队中任何线程,因此会从前向后遍历单链表,当遇到指定的线程时将其从单链表中移除,其删除的时间复杂度为O(n),这个过程是标准的单链表操作,不再画图说明。

红黑树

红黑树在插入,查询,删除三个操作上都有稳定的时间复杂度O(logn),适用于管理列队线程超过20以上的系统。在Zephyr中大多数情况下红黑树会使用大约2KB的代码量,存储敏感的系统不适合选择该算法。

线程插入列队时,在红黑树中依据线程优先级排序,同时为了辨别那个线程先加入列队会维护一个order_key,每插入一个线程到列队中order_key就加一,并将该order_key值和插入的线程绑定,因此越先插入的线程等待的时间就越久,对应的order_key就越小。当线程优先级一样时就以绑定给线程的order_key排序:

对红黑树列队进行查询时,需要取出优先级最高且等待最久的线程。将从根节点开始遍历,右叶子节点的优先级级比父节点的优先级高,如果右叶子节点和父节点的优先级相等,那么右叶子节点的order_key要比父节点小(order_key小的先加入列队,等待时间更长):

对红黑树列队进行删除时,会按照和查询一样的算法进行遍历,找到指定的线程后执行删除和变换红黑树,上图演示了该过程。

5.2.1.2 列队算法选择

在Zephyr中不是所有的列队都可以任意选择列队管理算法,用户要根据实际的需求选择Zephyr允许用列队算法。

就绪列队可选算法

就绪列队用于管理就绪线程,三种列队算法都可任选一种,通过下面配置项选择

  • 单链表队列:CONFIG_SCHED_DUMB=y

  • 红黑树:CONFIG_SCHED_SCALABLE=y

  • 多链表队列(CONFIG_SCHED_MULTIQ=y

内核对象等待列队

等待信号量,互斥量等内核对象的线程被放入内核对象等待列队,每个可等待的内核对象都有一个自己的等待列队,所有内核对象只能使用相同的列队等待算法,通过配置可以选择下面两种算法之一:

  • 单链表队列:CONFIG_WAITQ_DUMB=y

  • 红黑树:CONFIG_WAITQ_SCALABLE=y

Zephyr调度算法相关推荐

  1. Zephyr内核到1.5版本的改进

    Zephyr内核从1.0到1.5版本发生了很大改变,这些改变给开发人员带来了很大方便,具体如下: ①消除微内核和超微内核构建类型的分离 ②消除微内核应用程序中的MDEF ③更简单易用的内核API ④宽 ...

  2. c语言链表最高响应比优先,操作系统--最高响应比优先调度算法实验报告..doc

    操作系统--最高响应比优先调度算法实验报告. 进程调度一.实验题目与要求 编写程序完成批处理系统中的作业调度,要求采用响应比高者优先的作业调度算法.实现具体包括:首先确定作业控制块的内容和组成方式:然 ...

  3. LVS原理详解(3种工作方式8种调度算法)--老男孩

    一.LVS原理详解(4种工作方式8种调度算法) 集群简介 集群就是一组独立的计算机,协同工作,对外提供服务.对客户端来说像是一台服务器提供服务. LVS在企业架构中的位置: 以上的架构只是众多企业里面 ...

  4. 据说程序员等电梯的时候都想过调度算法

    作者:SUN's Cabin 链接:https://www.cnblogs.com/jianyungsun/archive/2011/03/16/1986439.html 1.传统电梯调度算法 1.1 ...

  5. linux中O(1)调度算法与全然公平(CFS)调度算法

    一.O(1)调度算法 1.1:优先级数组 O(1)算法的:一个核心数据结构即为prio_array结构体. 该结构体中有一个用来表示进程动态优先级的数组queue,它包括了每一种优先级进程所形成的链表 ...

  6. 负载均衡集群介绍、LVS介绍、LVS调度算法、 LVS NAT模式搭建

    负载均衡集群介绍 LVS介绍 lvs的NAT模式介绍 这种模式借助iptables的nat表来实现,用户的请求到分发器后,通过预设的iptables规则,把请求的数据包转发到后端的服务器上去,这些服务 ...

  7. http反向代理调度算法追朔

    标题索引 追朔原因 反代原理 调度算法 算法评估 追朔原因 http调度算法有多种,在nginx.haproxy.apache.keepalive中等等都有相对应的算法,但是算法根本原理是不变的 反代 ...

  8. 抢占式优先权调度算法

    在这种方式下,系统同样是把处理机分配给优先权最高的进程,使之执行.但在其执行期间,只要又出现了另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理机分配给新 ...

  9. 先来先服务调度算法(FCFS)

    先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度.当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内 ...

最新文章

  1. 简单html图片轮播_web前端入门到实战:简单的图片轮播
  2. 极速理解设计模式系列:23.装饰器模式(Decorator Pattern)
  3. 《WinForm开发系列之控件篇》Item18 FileSystemWatcher(暂无)
  4. Python快速教程博客园地址
  5. MySQL 索引详解
  6. ML之RS:基于用户的CF+LFM实现的推荐系统(基于相关度较高的用户实现电影推荐)
  7. 可以代表学计算机的标志,桌面上的图标可以用来表示
  8. maven插件依赖_当Maven依赖插件位于
  9. 解决mediawiki上传文件文件名是中文上传失败
  10. 微信支付开发(7) 刷卡支付
  11. cef 前进后台 实现_CefSpider: 一个基于Webkit,Cef框架构建爬虫,项目代号:“车风”,具备浏览器所有特性,欢迎你给我一个Star,你的Star是该项目前进的动力!...
  12. JAVA SE知识点总结
  13. 解决ASP.NET在IE10中Session丢失问题
  14. JavaScript学习(七十八)—实现对数据的浅拷贝和深拷贝
  15. 一些不好理解的名词解释
  16. 用Python标记识别人脸制作镂空图案的“笑脸”照片墙
  17. 计算机的存储容量以什么为单位,计算机中用来表示内存储器容量大小的基本单位是什么?...
  18. 租用美国的VPS主机需要注意什么
  19. 一场云端的“神仙打架”:BAT加华为的影响未来之争
  20. 使用Blob对象接收后台返回的图片流并展示到前端页面

热门文章

  1. 2023年Spring MVC相关面试题
  2. 采用sendmsg发送消息失败 recvmsg接收消息失败
  3. 163免费企业邮箱申请后怎么登陆?
  4. Android 架构之 MVC 架构模式
  5. 计算机创造奇迹英语作文,爱能创造奇迹
  6. 服务器中毒的原因有哪些?为什么服务器会中毒?
  7. 【带你吃透C++】C++动态内存管理
  8. python学习点滴记录-Day07
  9. unity中定时滑动公告板的实现及动态设置gridLayout的大小
  10. 东南电子开启申购:客户集中度较高,预计上市时市值约18亿元