一、前言

RT-Thread中提供的线程调度器是基于全抢占式优先级的调度,在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自身.系统总共支持256个优先级(0 ~ 255,数值越小的优先级越高,0为最高优先级,255分配给空闲线程使用,一般用户不使用。在一些资源比较紧张的系统中,可以根据情况选择只支持8个或32个优先级的系统配置)。在系统中,当有比当前线程优先级还要高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处理机进行执行。

二、线程优先级管理系统

在RT-Thread调度器的实现中,包含了一个共256个优先级队列的数组(如果系统最大支持32个优先级,那么这里将是一个包含了32个优先级队列的数组),每个数组元素中放置相同优先级链表的表头。这些相同优先级的列表形成一个双向环形链表,最低优先级线程链表一般只包含一个idle线程。

在scheduler.c中:

rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];

三、线程调度器函数接口(以下函数接口在src/scheduler.c中实现)

调度器初始化:
void rt_system_scheduler_init(void);
在系统启动时需要执行调度器的初始化,以初始化系统调度器用到的一些全局变量。
启动线程调度器:
void rt_system_scheduler_start(void);
在系统完成初始化后切换到第一个线程,可以调用下面的函数接口。
在调用这个函数时,它会查找系统中优先级最高的就绪态线程,然后切换过去执行。另外在调用这个函数前,必须先做idle线程的初始化,即保证系统至少能够找到一个就绪状态的线程执行。此函数是永远不会返回的。
向调度器中添加线程:
void rt_schedule_insert_thread(struct rt_thread *thread);
将线程从调度器中移除:
void rt_schedule_remove_thread(struct rt_thread *thread);
线程调度:
void rt_schedule(void);
让调度器执行一次线程的调度。
调用这个函数后,系统会计算一次系统中就绪态的线程,如果存在比当前线程更高优先级的线程时,系统将切换到高优先级的线程去。上层应用程序一般不需要调用这个函数。
进入临界区,调度器上锁:
void rt_enter_critical(void);
调用这个函数后,调度器将被上锁。在系统锁住调度器的期间,系统依然响应中断,如果中断唤醒了的更高优先级线程,调度器并不会立刻执行它,直到调用解锁调度器函数才尝试进行下一次调度。
同中断锁一样把调度器锁住也能让当前运行的任务不被换出,直到调度器解锁。但和中断锁有一点不相同的是,对调度器上锁,系统依然能响应外部中断,中断服务例程依然能进行相应的响应。所以在使用调度器上锁的方式进行任务同步时,需要考虑好任务访问的临界资源是否会被中断服务例程所修改,如果可能会被修改,那么将不适合采用此种方式进行同步。 退出临界区,调度器解锁:
void rt_exit_critical(void);
当系统退出临界区的时候,系统会计算当前是否有更高优先级的线程就绪,如果有比当前线程更高优先级的线程就绪,将切换到这个高优先级线程中执行;如果无更高优先级线程就绪,将继续执行当前任务。
注:rt_enter_critical/rt_exit_critical可以多次嵌套调用,但每调用一次rt_enter_critical就必须相对应地调用一次rt_exit_critical退出操作,嵌套的最大深度是65535。 返回调度器锁嵌套计数:
rt_uint16_t rt_critical_level(void)
{
return rt_scheduler_lock_nest;//0表示没有调度器锁
}
调度器锁能够方便地使用于一些线程与线程间同步的场合,由于轻型,它不会对系统中断响应造成负担;
但它的缺陷也很明显,就是它不能被用于中断与线程间的同步或通知,并且如果执行调度器锁的时间过长,会对系统的实时性造成影响(因为使用了调度器锁后,系统将不再具备优先级的关系,直到它脱离了调度器锁的状态)。

RT-thread内核之线程调度器的更多相关文章

  1. 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?

    线程调度器是一个操作系统服务,它负责为 Runnable 状态的线程分配 CPU 时间. 一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现.同上一个问题,线程调度并不受到 Java 虚拟 ...

  2. Effective Java 第三版—— 84. 不要依赖线程调度器

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  3. 【RxJava Demo分析】(二)Schedulers线程调度器 · Hans Zone

    用Schedulers(调度器)实现多任务(并发,Concurrency)的例子 废话不多说我们看一下有关于RxJava的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  4. ucore操作系统学习(六) ucore lab6线程调度器

    1. ucore lab6介绍 ucore在lab5中实现了较为完整的进程/线程机制,能够创建和管理位于内核态或用户态的多个线程,让不同的线程通过上下文切换并发的执行,最大化利用CPU硬件资源.uco ...

  5. SQL Server的thread scheduling(线程调度)

      https://www.zhihu.com/question/53125711/answer/134461670 https://www.zhihu.com/question/53125711   ...

  6. RT Thread 通过ENV来配置SFUD,操作SPI Flash

    本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...

  7. STM32 + RT Thread OS 学习笔记[二]

    串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1.   目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...

  8. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  9. Tomcat内核之类加载器工厂

    Java虚拟机利用类加载器将类载入内存,以供使用.在此过程中类加载器要做很多的事情,例如读取字节数组.验证.解析.初始化等.而Java提供的URLClassLoader类能方便地将jar.class或 ...

随机推荐

  1. CF 1051 F. The Shortest Statement

    F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...

  2. c++ 重载运算与类型转换

    1. 基础概念 重载的运算符是具有特殊名字的函数:(重载运算符函数,运算符函数.重载运算符) 依次包含返回类型,函数名(operator=),参数列表,函数体. 只有重载的函数调用运算符operato ...

  3. spring-boot、spring-data-jpa、hibernate整合

    一.Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. ...

  4. unity3d 角色头顶信息3D&2D遮挡解决方案(一)

    先上效果图,只凭文字描述,脑补应该有些困难- - 如图:有三个角色(我们暂且从左到右叫它们A.B.C),一个2D UI(中间动作选择的框框),一个cube(右边的方块) cube挡住了角色C的头顶信息 ...

  5. 根据wsdl生成服务端代码

    场景描述 最近在和一家公司做业务接口对接,由他们那边回调我们这边,对方直接扔过来一个webservice的wsdl文件,让我们按照他们的规范来做webservice服务, 大多数的对接应该是我们创建完 ...

  6. 「日常训练」Two Substrings(Codeforces Round 306 Div.2 A)

    题意与分析 一道非常坑的水题.分析醒了补. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back ...

  7. 怎样从Java转换到Kotlin代码:现在就开始使用Kotlin(KAD 29)

    作者:Antonio Leiva 时间:Jul, 4, 2017 原文链接:https://antonioleiva.com/kotlin-from-java/ Kotlin最神奇特性之一是它能与Ja ...

  8. Linux命令应用大词典-第26章 模块和内核管理

    26.1 lsmod:显示内核中模块的状态 26.2 get_module:查看内核模块详细信息 26.3 modinfo:显示内核模块信息

  9. Vue-cli 工具 / 通过 Vue-cli 工具重构 todoList

    本博文归纳在 Vue 学习过程中, Vue-cli 工具的使用说明.除此之外还通过 Vue-cli 工具将之前 Vuejs 基本语法当中实现的 todoList 进行重构. 安装 npm instal ...

  10. 论文笔记:Attentional Correlation Filter Network for Adaptive Visual Tracking

    Attentional Correlation Filter Network for Adaptive Visual Tracking CVPR2017 摘要:本文提出一种新的带有注意机制的跟踪框架, ...