[019] [RT-Thread学习笔记] 线程位图调度算法

rt-thread的位图调度算法分析 序言 期待读者 本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语句不会介绍,但是并不要求读者有过多的C基础,比如指针和链表等不会要求太多,后面在分析代码时,会附带地介绍相关的知识,如果您已经精通了C语言的指针则可以略过相关的介绍。除此之外,不再假设读者拥有任何知识。 如何阅读代码 就以rt-thread内核代码为例(注,指rt-thread的kernel代码), 阅读详情
RT-Thread
学习笔记
线程优先级链表
位图算法

RT-Thread版本:4.0.5
MCU型号:STM32F103RCT6(ARM Cortex-M3 内核)

1 线程优先级链表

每个线程控制块都带有一个链表成员,根据优先级将thread->slist插入对相应优先级链表中,对于相同优先级采取时间片轮转调度方式,若线程当前时间片已用完,且其所在的优先级队列为当前系统最高优先级,则调用rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),&(thread->tlist))将此线程插入到末尾,切换到表头线程运行。
image-20220326005605388

对于不同优先级,采取抢占式调度,每次会从优先级链表找出当前最高优先级链表(即非空),然后在其中取出第一个线程运行。
image-20220326005734598

2 位图算法

查找最高优先级的线程,首先得先找到当前最高的就绪优先级,最容易想到的调度算法(调度算法1):

    for(i = 0; i < 256; i++)
    {
        if(rt_thread_priority_table[i] != NULL)
            break;
    }
    highest_ready_priority = i;    

此算法可以找到当前最高的就绪优先级,但当最高优先级为255时,每次都要遍历完优先级表才能找到,时间复杂度O(n)

每个优先级链表是否存在线程,可以用一个bit位来表示,对于256级的线程,则共需要256个bit位,即32字节,因此引入:

rt_uint8_t rt_thread_ready_table[32];

数组的第一个字节的bit0表示优先级0,bit7表示优先级7,第而个字节的bit0表示优先级8,以此类推:

bit:    7   6   5   4   3   2   1   0
byte0 |007|006|005|004|003|002|001|000|
byte1 |0l5|014|013|012|011|010|009|008|
.................................
byte31|255|254|253|252|251|250|249|248|

这32个字节所组成的256个bit,他们的排列方式很像一张图(map),所以这种方式就别称为位图(bit map)

如创建了一个优先级为125的线程,并且加入到就绪链表中,则将字节 15 (125 / 8)的bit5(125 % 8)置1,即rt_thread_ready_table[125/8].BIT5 = 1。

此时遍历rt_thread_ready_table[32]数组每个bit位即可找到最高就绪优先级(调度算法2):

for(i = 0; i < 32; i++)
{
    for(j = 0; j < 8; j++)
    {
        if (rt_thread_priority_table[i] & (1<<j) ) 
            break;//这就是找到最低的那个为1的bit位置了。
    }
    //下面就是我们找到的最高优先级
    highest_ready_priority = i * 8 + j;
}

对于此算法,若BIT0为1,则执行一次即跳出循环,如果BIT0-BIT254都是0,仅BIT255为1,则循环256次。 平均循环次数32*8/2次,时间复杂度依然为O(n)。

现在将位图看作一个变量,并假定当前优先级范围为0~7,则位图变量可以用一个字节表示。当bit0为1时,最高优先级为0,当位图变量为255时,最高优先级也为0(此时bit0还是为1),因此当位图变量取0-255之间的任意一个数字时,它的最低为1的BIT位置都是预知的(对应最高优先级)。

我们可以预先将位图变量的所有取值所对应的最高优先级计算出来,并存成一张表格,然后就可以避免算法2中的for循环,而只需要查表即可,用空间换取时间。

例如,8位位图变量所有可能取值对应的最高优先级:

位图变量取值最高优先级
0x00均为0,无最高优先级
0x01bit0 = 1,最高优先级为0
0x02bit1 = 1,最高优先级为1
0x03bit0 = 1,最高优先级为0
0x04bit2 = 1,最高优先级为2
…
0xfebit1 = 1,最高优先级为1
0xffbit0 = 1,最高优先级为0

最终可得到如下的表:

const rt_uint8_t __lowest_bit_bitmap[] =
{
    /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};

对于0x00其值虽为0,但不代表最高优先级就为0。

当优先级为0~7时,可直接查表找到当前最高的优先级,如当前线程优先级为1/3/5,则bit1、bit3、bit5置1,位图变量取值为0x2A,查表__lowest_bit_bitmap[0x2A] = 1,即可判断当前最高优先级为1。

8优先级可以绘制2^8字节表格来解决,如果32优先级,则需绘制2^32 = 4G字节表格,显然这是不可接受的。

32个优先级,即优先级位图变量可以使用u32型,即变量rt_thread_ready_priority_group,对这4个字节从字节0开始依次查表,如果字节0中非0,则最高优先级一定存在于字节0中,我们对字节0查表rt_lowest_bitmap,即可以得到最高优先级。 如果字节0为0,字节1非0,我们对字节1查表得到的是字节1中为1的最低bit位,然后加上8,就是系统的最高优先级,其他字节同理。调度算法3:

   /*
     * rt_thread_priority_bitmap 用来表示当前系统优先级位图。
     * highest_ready_priority表示当前系统中最高优先级
     */
    if (rt_thread_priority_bitmap & 0xff)
    {
        highest_ready_priority = rt_lowest_bitmap[rt_thread_priority_bitmap & 0xff];
    }
    else if (rt_thread_priority_bitmap & 0xff00)
    {
        highest_ready_priority = rt_lowest_bitmap[(rt_thread_priority_bitmap >> 8) & 0xff] + 8;
    }
    else if (rt_thread_priority_bitmap & 0xff0000)
    {
        highest_ready_priority = rt_lowest_bitmap[(rt_thread_priority_bitmap >> 16) & 0xff] + 16;
    }
    else
    {
        highest_ready_priority = rt_lowest_bitmap[(rt_thread_priority_bitmap >> 24) & 0xff] + 24;
    }

32优先级位图查表算法rt-thread如下:

int __rt_ffs(int value)
{
    if (value == 0) return 0;

    if (value & 0xff)
        return __lowest_bit_bitmap[value & 0xff] + 1;

    if (value & 0xff00)
        return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9;

    if (value & 0xff0000)
        return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17;

    return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;
}

rt-thread位图变量最低有效位从1开始,因此相对调度算法3多+1。

当前系统支持的线程优先级为256时,可以用位图数组rt_uint8_t rt_thread_ready_table[32]来表示优先级,此时采用算法3思路,可对这32个字节依次查表,但为了提升系统实时调度的性能,我们需要对算法3进行改进,即使用二级位图。

所谓二级位图,即先确定32个字节中最低的非0的字节,因此需要对这32个字节引入一个32个bit的位图变量,每一个bit位表示对应的字节是否为0。rt-thread采用的变量名为rt_thread_ready_priority_group(与32位优先级调度算法中的位图变量同名)

根据上面的分析,要想使用这个二级位图算法,rtt在跟踪线程的状态转换时,不仅需要维护256bit的位图变量数组rt_thread_ready_table[thread->number] |= thread->high_mask,还需要维护32bit的 字节位图变量 rt_thread_ready_priority_group。参看线程启动函数和插入调度就绪链表函数的代码(rt-thread位图变量最低有效位从1开始):

rt_err_t rt_thread_startup(rt_thread_t thread)
{
    [...]
    /* set current priority to init priority */
    thread->current_priority = thread->init_priority;
    
#if RT_THREAD_PRIORITY_MAX > 32
(1) thread->number      = thread->current_priority >> 3;            /* 5bit */
(2) thread->number_mask = 1 << thread->number;
(3) thread->high_mask   = 1 << (thread->current_priority & 0x07);   /* 3bit */
#else
(4) thread->number_mask = 1 << thread->current_priority;
#endif
    [...]
}
 
void rt_schedule_insert_thread(struct rt_thread *thread) 
{
    [...]
#if RT_THREAD_PRIORITY_MAX > 32
(5) rt_thread_ready_table[thread->number] |= thread->high_mask;
#endif
(6) rt_thread_ready_priority_group |= thread->number_mask;
    [...]
}

32优先级:

  • (4) 将thread->number_mask与当前优先级相对应的位置1
  • (6)修改位图变量rt_thread_ready_priority_group对应的位,方便后面直接查表__lowest_bit_bitmap

256优先级:

  • (1) 右移3位相当于将当前线程的优先级/ 2^3,因此thread->number表示当前这个优先级对应的位图32个字节中的第几个字节(number范围0~31)
  • (2)thread->number_mask为thread->number的掩码,方便后续位或/位与操作
  • (3)thread->current_priority & 0x07即thread->current_priority%8, thread->high_mask表示该优先级在上面字节中的第几个bit,例如bit4,则thread->high_mask = 1<<4,这样同样方便后续位或/位与操作
  • (5)将当前优先级所在的字节对应的位置位

rtt首先确定32个字节的位图中,非0的最低的那个字节,然后再查表得到这个字节非0的最低那个bit。这两步骤正好可以利用两次上面的表格rt_lowest_bitmap。

最终的rt_schedule函数:

void rt_schedule(void)
{
    [...]
#if RT_THREAD_PRIORITY_MAX <= 32
        highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#else
        register rt_ubase_t number;
    
        number = __rt_ffs(rt_thread_ready_priority_group) - 1;
        highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#endif
    [...]
}

-1是因为在__lowest_bit_bitmap中,rt-thread位图变量最低有效位从1开始,但最高优先级是从0开始的。

最终实现的调度算法时间复杂度为O(1)。

可以看出位图调度算法的核心就是查找字节最低非0 bit位的查表法软件实现,是整个位图调度算法的核心。ARM公司提供专门的指令获取寄存器最低位,只要几条汇编语句就可以完成同样的功能,而且性能更好,cortex-m3中:

// libcpu/arm/cortex-m3/cpuport.c
__asm int __rt_ffs(int value)
{
    CMP     r0, #0x00
    BEQ     exit

    RBIT    r0, r0			; 位反转(把一个32位整数用2进制表达后,再旋转180度)
    CLZ     r0, r0			; 计算前导零的数目
    ADDS    r0, r0, #0x01

exit
    BX      lr
}
  • RBIT指令用法
LDR		R1, =0xB4E10C23	; R1 = 1011,0100,1110,0001,0000,1100,0010,0011
RBIT	R0, R1			; R0 = 1100,0100,0011,0000,1000,0111,0010,1101

确实是水平旋转180°。

举例:value = 0xf200

汇编实现的查找最低非0 bit位:

RBIT    r0, r0			; 1111,0010,0000,0000 -> 0000, 0000, 0100, 1111 
CLZ     r0, r0			; 前导零数目r0 = 9, 即value 最低非0 bit位为bit9  (从0开始)
ADDS    r0, r0, #0x01	

位图查表法实现的查找最低非0 bit位:

__lowest_bit_bitmap[(0xf200 & 0xff00) >> 8] + 9;
__lowest_bit_bitmap[0xf2] + 9;
1+9 = 10	// 从1开始

两者都能找到最低非0 bit位,但显然汇编法时间复杂度和空间复杂度都优于位图查表法,但需要内核支持这些汇编指令。

参考:

END

RT-Thread源码解析(1)——调度器与优先级链表设计 本文深入解析RT-Thread实时操作系统的调度器核心设计与优先级链表实现机制。通过分析优先级位图(rt_thread_ready_priority_group)和就绪链表数组的协同工作原理,详解线程状态切换、最高优先级线程查找算法(__rt_ffs)及调度器初始化流程,为开发者理解RT-Thread源码框架和实时系统调度提供实践指导。 阅读详情

相关推荐

【信息科学与工程学】计算机科学与技术——第二百二十五篇 架构设计 01 RTOS架构01

好的,根据您的要求,我将为您构建一个关于“实时系统设计方案中的知识体系”的详细纵向输出。内容将严格遵循您提供的格式,并重点扩展“核心知识点/其他知识点列表”和“数学表达式与方程式列表及详细数学建模与数值设计”这两个部分,确保其内容均超过1000字。本知识模块是实时系统设计的基石。它确保了系统能够在严格的时间约束内完成指定计算任务,是保障系统和的核心。在航空航天、自动驾驶、工业控制、金融交易等对时间敏感的应用中,正确的调度策略与分析是避免灾难性后果(如错过截止时间导致系统失效)的关键。

weixin_49199313的博客 191

线程

java线程 Java线程与系统内核线程 Java线程创建依赖系统内核,创建一个线程开销非常大,所以要使用线程池 线程生命周期 创建一个线程对象(NEW状态),调用了start方法,线程进入就绪状态,当CPU分配时间片执行线程(RUNNING状态),期间如果调用了join,sleep,wait等设置了超时时间的方法,进入超时等待状态,调用join,wait等进入等待状态,等待状态超时时间结束,或者被唤醒,重新进入到就绪状态,如果对象加锁,没争抢到锁的进入阻塞状态,获取到锁运行状态,当线程执行完就会进入终

u013716429的博客 233

【信息科学与工程学】【广告科学】第四十四篇 广告平台投放和广告计费类算法01

全行业的中国企业广告投放模型总表。行业分类依据《国民经济行业分类》(GB/T 4754—2017)的门类/大类 ,产品层参考"主营产品统计代码"行业—产品映射 ,平台算法以巨量引擎、腾讯广告等官方文档为硬支撑 ,合规部分严格对齐《互联网广告管理办法》以及2026年市场监管部门最新合规提示 。编号类型(门类)行业(大类)企业及产品内容列表投放模型投放平台投放人群欲望激发维度面向人群模式(地域/文化/年龄/角色)001A 农林牧渔01 农业北大荒/中粮:五常大米、面粉、食用油、杂粮品牌曝光 + 电商转化双轨(C

weixin_49199313的博客 1641

验证:为RT-Thread内核增加一种新的查找字节最低非0位的算法

人生最苦痛的是梦醒了无路可走。做梦的人是幸福的;倘没有看出可走的路,最要紧的是不要去惊醒他。 – 鲁迅 《娜拉走后怎么样》 概述 该篇文章来源于:《验证:为RT-Thread内核增加一种新的查找字节最低非0位的算法》 在 RT-Thread 的内核代码中,有一种查找最低非零位的算法,主要采用查表的方法,通过时间换空间的方式,为系统寻找线程的最高优先级提供了一种高效的方法。 通过查看内核代码里面的 kservice.c 文件,我们可以看到如下源代码: const rt_uint8_t __lowest_.

Eureka1024的博客 598

AMP架构下的核间通信:RPMSG与共享内存原理详解

本文以RK3568等异构多核硬件为例,深入浅出解析了AMP架构下核间通信的核心逻辑,阐明RPMSG并非替代共享内存,而是以共享内存为数据载体、硬件信箱为中断通知工具、VirtIO为数据管理规则,构建的标准化高层协议与框架,为开发者提供简洁API,实现不同操作系统核心间高效通信。

qq_61335271的博客 2049

ARKit面部动画实战:如何用blend shape让数字人表情更自然(附中文对照表)

本文深入探讨了如何利用ARKit的blend shape技术驱动数字人面部动画,以实现更自然生动的表情。文章提供了详细的blend shape中文对照表,并分享了实战技巧,包括构建复合表情动画序列、处理不对称性与微表情,以及性能优化策略,旨在帮助开发者高效提升数字人的表情表现力。

weixin_29292535的博客 322

一种新的高效的寻找字节最低非0位的有效算法

追逐梦想就是追逐自己的厄运,在满地都是六便士的街上,他抬起头看见了月光。 毛姆 --《月亮与六便士》 一、前言 该文章见github仓库:https://github.com/Eureka1024/An-effective-method-for-finding-the-lowest-non-0bit-bit-of-byte 本文目的是介绍一种新的查找字节最低非0位的算法,该算法比一般的位图算法更省空间,同时对于 32bit以及更长的字节,该算法查找字节最低非0位的实现路径也更加高效。 该算法的原理为:假.

Eureka1024的博客 2099

【信息科学与工程学】【通信工程】第三百零五篇 网络中的几何/拓扑/离散数学/组合数学 01

矩 accountant 累计。Bluetooth LE广告包。单细胞RNA-seq计数矩阵。梯度AllReduce算法。蛋白质-蛋白质相互作用网络。联邦学习本地epoch数。资本资产定价模型beta。联邦学习客户端采样比例。联邦学习服务器聚合权重。变分量子本征求解器参数。抵押贷款支持证券现金流。数据加载器工作进程数。流水线并行微批次数量。学习感知图像块相似度。边缘设备CPU利用率。ZigBee网络地址。量子近似优化算法参数。宇宙微波背景温度涨落。

weixin_49199313的博客 235

LVGL仪表盘实战:5分钟用lv_meter打造汽车仪表UI(附完整代码)

本文详细介绍了如何使用LVGL的lv_meter组件在5分钟内构建专业汽车仪表盘UI。从环境配置、刻度定制到指针动画和性能优化,提供完整代码示例和实战技巧,帮助开发者快速实现嵌入式设备上的高效仪表盘设计。

k5l6m的博客 414

PMP--工件

合同是指对双方都有约束力的协议,强制卖方提供规定的产品、服务或结果,以及强制买方支付相应的费用。它还可能包括处于中间状态的特性,例如已设计但尚未构建的特性、质量保证中的特性或测试中的特性。RACI 矩阵是一种常见的方法,用于显示执行、担责、咨询或知情,且与项目活动、决策和可交付物有关的干系人。计划是提议的实现某种目标的方式。在项目开始前或开始时创建的文件,涉及与项目有关的战略、商业或高层级的信息。或 © 它们是用特定方法创建的结果,例如,虽然成本估算结果是一个重要工件,它们是用不同估算方法得出的结果。

stqer的博客 1665

μC/OS-II与RT-Thread对比——任务调度

在任务调度器的实现上,μC/OS-II和RT-Thread都采用了位图调度(bitmap scheduling),任务优先级的值越小则代表具有越高的优先级,主要区别在于实现形式,是采用多级队列的形式,还是纯位图的形式。在位图调度下,每当需要进行调度时,从最低位向最高位查找出第一个置 1 的位的所在位置,即为当前最高优先级,然后从对应优先级就绪队列获得相应的任务控制块,整个调度器的实现复杂度是 O(

古月居 2万+

MATLAB基础应用精讲-【数模应用】信用评分模型(附R语言和python代码实现)

信用评分模型是近年来兴起的一种为了保障银行和其他金融部门的金融安全而设立的一种关于人身金融权限的划定模型。该模型指根据客户的信用历史资料,利用一定的信用评分模型,得到不同等级的信用分数,根据客户的信用分数,来决定客户所可以持有的金额权限,从而保证还款等业务的安全性。而随着在现代社会和公司中,贷款,信用卡的作用日渐突出,信用评分模型的发展前景不可估量。信贷风险是指借款人因偿还贷款或履行合同承诺而破产而产生损失的可能性。传统上,它与贷款人无法偿还所欠利息和本金、影响现金流和增加装配成本所产生的风险有关。

qq_36130719的博客 364

OS-基于位图的RR调度算法

OS-基于位图的RR调度算法 位图原理 有这么个业务场景,在10亿个不重复的随机整数中查找某个数 x 是否存在其中,32为操作系统,4G内存。 普通算法 我们可以使用10亿个int类型的空间来存储这10亿个数据,然后再进行x查找。这1亿个int数据就需要占用:1000000000*4 = 3.72G字节空间。光存储这10亿数据就要花到这么多内存实在是太恐怖了。其次在查找的时候,最快的hash查找,光数据结构的空间都要需要很庞大的内存空间。 位图算法 我们先把数据量缩小,假设只有10个随机数(0-9)

GoolyOh的专栏 712

Midscene.js(2):代码集成 + 桥接模式(Bridge Mode)的使用「喂饭教程」

本文将手把手教你从零开始搭建一个 Node.js 项目,集成 Midscene.js,并利用其桥接模式实现对 Chrome 浏览器的自动化操作。我们将通过具体的实例,来展示 Midscene.js 的便捷性与 AI 能力的结合。

blues_C的博客 1843

深度解析大众点评反爬机制:构建高可用店铺评论采集系统(2026最新实战)

在中文互联网数据采集领域,大众点评(现归属美团)始终占据着特殊地位。其丰富的UGC(用户生成内容)包含了超过2亿条真实店铺评论、数百万家商户的详细POI信息以及用户行为数据,对商业分析、口碑监测、本地生活趋势研究具有不可替代的价值。然而,大众点评的安全团队投入了顶级资源构建反爬系统——从请求签名、行为验证到设备指纹,其防御强度甚至超过多数电商平台。本文将完整呈现一套2026年依然有效的技术方案,包括破解核心参数_token、动态代理池维护、无头浏览器指纹伪装等,最终产出一个生产级采集框架。目录。

2201_76125261的博客 808

【RT-Thread内核详解系列】基于优先级的全抢占式调度算法的实现

The unexamined life is not worth living. 未经审视的人生是不值得过的。 – 苏格拉底 一、原理概述 RT-Thread 是一款嵌入式实时操作系统(RTOS),同时也是一款优秀的物联网操作系统,相对于裸机的轮询调度算法,它使用的线程(任务)调度算法是基于优先级的全抢占式多线程调度算法,该算法大大增强了系统的实时响应,大大扩展了系统的应用场景。 该调度算法在每次调度任务时,总会选择优先级最高的就绪任务执行,保证优先级高的任务得到最及时的响应。 下面,我们来详细讲解该调.

Eureka1024的博客 4044

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

优先级链表

优先级链表

weixin_45428910的博客 535

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

使用链表的优先级队列

元素本身的值可以用于分配优先级。例如:最高值的元素被视为最高的优先级元素。但是,在其他情况下,我们可以假设最小值的元素作为最高优先级元素。在其他情况下,我们可以根据我们的需要确定优先级。优先级队列是一种特殊类型的队列,其中每个元素都是与优先级相关联,并根据其优先级提供服务。如果元素有相同的优先级,那么根据它们在队列中的排列顺序。在队列中,根据先进先出规则,而在优先级队列中,则根据优先级删除这些值。根据优先级删除,最小值具有高优先级被删除。

Do my best! 1257

RT-Thread的位图调度算法分析(适配RTT更新版)

RT-Thread的内核调度算法 rt-thread的调度算法为基于优先级调度和基于时间片轮转调度共存的策略。rt-thread内核中存在多个线程优先级,并且支持多个线程具有同样的线程优先级。线程级别数目在rtconfig.h中以宏定义的方式配置, 当系统存在多个线程时,可能的情况是,某些线程具有不同的线程优先级,但是还有一些线程具有相同的优先级。rt-thread采用的调度策略是: 不...

FILLMOREad的博客 1343

UCOSII学习笔记——任务调度之优先级位图法

UCOSII学习笔记——任务调度机制1 任务描述2 创建任务2.12.4 创建任务挂载就绪队列 1 任务描述 2 创建任务 2.1 2.4 创建任务挂载就绪队列 任务堆栈初始化和OS_TCB初始化完成后,需要将新创建的任务挂载到就绪队列,以便供OS_Sched调度,以下代码即表示挂载过程: OSRdyGrp|= ptcb->OSTCBBitY; //挂载任务到就绪队列 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; ...

weixin_42369760的博客 1457

Linux进程第十四讲——进程调度器底层揭秘:位图与O(1)机制如何实现高效优先级调度

本文深入解析了Linux O(1)进程调度器的底层机制,重点介绍了位图(Bitmap)和优先级数组如何协同工作实现高效调度。传统调度器采用O(n)遍历方式,而O(1)调度器通过位图标记队列状态、优先级数组分类存储进程,结合双队列设计,实现了与进程数量无关的恒定调度时间。文章通过代码示例演示了位图如何快速定位最高优先级进程,并分析了优先级数组的结构设计,揭示了"调整优先级本质是改变进程在数组中的位置"这一核心原理,为理解Linux高效进程调度提供了底层视角。

Maple_land的博客 930

RT_Thread——(二)线程调度与管理

RTT

Lxy_meteor的博客 2703

FreeRTOS应用之任务管理

@TOC 任务 任务

weixin_42617385的博客 663

链表

链表 前言:LinkedList<T>是一个双向链表,其元素指向他前面和后面的元素。如下图所示,这样一来,通过移动到下一个元素可以正向的遍历整个链表。通过移动到前一个元素可以反向遍历整个链表。 链表的优点:如果将元素插入列表的中间位置,使用链表就会非常快。在插入一个元素时,只需要修改上一个元素的Next引用和下一个元素的Previous引用,使他们引用所插入的元素。在...

diezhang4363的博客 183

RT-Thread源码-__rt_ffs函数剖析

在RT-Thread中,获取已就绪最高优先级线程索引会使用此函数。而此函数所包含的算法为bitmap算法。 为什么使用此函数获取已就绪最高优先级线程索引?为什么使用bitmap算法?目的在于提升索引值获取的执行效率,以及保证系统的稳定执行。 通常,为了获取已就绪最高优先级线程,最简单的方法就是遍历当前线程列表中的每一个线程状态及优先级,通过比较最后获取。而这种方法会随着最大支持线程数的增加而增加时间复杂度,且执行时间非恒定,影响系统的稳定。 此函数在RT-Thread中实现如下, const rt_ui.

qq_36535265的博客 952
上一篇: [018] [RT-Thread学习笔记] 上下文切换分析
下一篇: [020] [RT-Thread学习笔记] 消息队列
柯西的彷徨
博客等级 码龄8年 790粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西的彷徨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值