多线程是实时操作系统外面最重要的知识点之一,要学习RTOS,多线程是必须(没错,是必须)要熟练掌握的内容,只有熟练掌握多线程的应用,能力在平时的我的项目工作外面用好实时操作系统。

对于多线程的应用和治理,RT-Thread官网提供了比拟丰盛的文档作为参考,具体能够查看以下链接:https://www.rt-thread.org/doc...,本文是对RT-Thread多线程学习后的总结,并尝试从如图所示的以下几个方面进行总结。

什么是多线程?

在单片机上学习RT-Thread的多线程之前,要先把“过程”这个概念先放一边,因为单片机是没有多过程概念的。单片机运行操作系统,不论多少个工作,他们都是多个(或单个)线程之间进行解决这些工作,单片机个别不波及多过程。

什么是多线程?在哪些状况下要用到多线程?先来举一个音乐播放器的例子,这个音乐播放器要做以下这些根本的工作:读取音乐文件并播放、读取歌词并显示、读取MV文件并播放。

如果这三个根本的工作不必多线程来实现,单片机应用裸机的形式去做这三个工作的话,必然会造成音乐播放卡顿,歌词显示不同步,MV视频播放与音乐不同步。

因为单片机做这三件事件的时候,是Step by Step的,必须实现一件事件之后,再去做下一件事件,这三件事件是有先后顺序的,并且一直循环反复,如下图所示。

而如果采纳多线程这种形式来实现这个工作,这个过程就变得绝对简略了,比方针对音乐播放器这个场景,能够设计这几个线程来解决:音乐文件读取线程,歌词文件读取线程,MV文件读取线程,音视频和歌词显示线程。

(此处只为举例形容多线程的概念,不思考音视频编解码的简单过程,不思考线程同步,实际上音乐播放器的实现比此处形容更简单)

音乐文件读取线程只负责从磁盘读取音乐文件,歌词文件读取线程和MV文件读取线程也是同样的情理,它们只做文件读取工作,而音视频和歌词显示线程,是负责把读取到的数据进行显示。这几个线程的工作过程,如下图所示。

如上图所示,这几个工作看上去是“同时”进行的,每个工作都只实现本人的事件,通过多线程,就能够把本来串行实现的工作改为并行实现,大大提高了工作效率。

所以,艰深地对多线程进行了解,就是把一个比拟大型的工作,拆分为多个小型的工作,而后通过正当的调度形式,让这几个小型的工作“同时”运行,当这几个小型工作实现后,大型的工作也随之实现,这样能够大大提高工作的实现效率。
多线程的几种状态

对于运行RT-Thread操作系统,线程都处于以下五种状态的其中一种(初始状态、就绪状态、运行状态、挂起状态、敞开状态),通过调用操作系统提供的接口函数,能够让线程在这五种状态中进行来回切换。

对于这五种线程状态的形容,如下表所示:

多线程的API函数

如上图的状态机所示,多线程能够通过调用零碎提供的函数接口,在多个状态之间进行切换。这些API函数在官网提供的参考文档外面都有具体的阐明形容,以下列举一些比拟罕用的函数接口。

多线程的利用示例

多线程的利用示例,次要是为了验证以上的多线程API接口函数,并且通过试验景象察看多线程的运行状况,次要有以下三个示例:

示例源码下载链接:https://github.com/embediot/r...

1、线程动态创建与动态创立、线程退出示例。

这个示例次要是通过动静形式创立线程1,,通过动态形式创立线程2,线程1的优先级比线程2的优先级低,因而能够被线程2抢占。线程2运行10次后就会被动退出,初始化代码如下图所示。

2、雷同优先级线程的工夫片轮转调度示例。

这个示例次要是通过动静形式创立线程1和线程2,这两个线程都是雷同的优先级,并且共用一个线程入口函数,次要是通过传入不同的线程参数以辨别线程1和线程2。线程2运行所占用的工夫片比线程1要少,因而线程2运行的工夫比拟短,初始化代码如下图所示。

3、线程调度器的钩子函数应用示例。

这个示例次要测试了线程在进行调度时,对于钩子函数的调用状况。通过线程调度器的钩子函数,打印出线程间的切换信息,初始化的代码如下图所示。

多线程利用的注意事项

在应用RT-Thread实时操作系统进行多线程利用开发的时候,应该要留神以下事项:

1.RT-Thread的线程调度器是抢占式的,也就是可能保障就绪队列外面,最高优先级的工作总能取得CPU的使用权,在工作设计的时候,要充分考虑好工作的优先级。

2.在硬件中断服务程序运行期间,如果有高优先级的工作就绪,那么被中断的低优先级工作将被挂起,高优先级的工作将会取得CPU的使用权。

3.每个线程都有独立的线程栈,用来保留线程调度时上下文的信息,因而在创立线程调配栈空间的时候,要充分考虑栈的大小。

4.在线程的循环体外面,应该要设置某些条件,在必要的时候被动让出CPU的使用权,特地对于高优先级的线程,如果程序外面有死循环操作而又不被动让出CPU使用权,那么这个线程将会始终占用CPU,并且低优先级的线程永远不会被调度执行。

5.对于没有始终循环执行的线程,线程执行结束后,资源的回收状况实际上是在闲暇线程外面进行的,线程变为敞开状态后,不代表资源马上被回收。

6.零碎闲暇线程是最低优先级且永远为就绪状态的,闲暇线程是一个死循环,永远不会被挂起,但能够被其余高优先级工作抢占,闲暇线程次要执行僵尸线程的资源回收工作。

7.闲暇线程也能够设置钩子函数,用来进行功耗治理,看门狗喂狗等工作。

8.通过动静形式创立的线程,须要设置好零碎堆内存的大小,而通过动态形式创立的线程,线程栈和线程句柄在程序编译的时候就曾经确定,不能被动态分配,也不能被开释。

9.大多数线程都是在一直循环执行的,无需进行删除,个别不举荐被动删除线程。线程运行结束后,系统调度器将会主动把线程退出僵尸队列,资源回收工作将在闲暇线程外面进行。

感激浏览!

原文链接:https://club.rt-thread.org/as...