0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT-Thread多线程学习后的总结

RTThread物联网操作系统 来源:RTThread物联网操作系统 作者:RTThread物联网操作 2021-01-13 16:34 次阅读

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

关于多线程的使用和管理,RT-Thread官方提供了比较丰富的文档作为参考,具体内容可以查看以下链接:

https://www.rt-thread.org/document/site/programming-manual/thread/thread/

本文是对RT-Thread多线程学习后的总结,并尝试从如图所示的以下几个方面进行总结。

4c0119c4-51a5-11eb-8b86-12bb97331649.png

什么是多线程?

单片机上学习RT-Thread的多线程之前,要先把“进程”这个概念先放一边,因为单片机是没有多进程概念的。单片机运行操作系统,不管多少个任务,他们都是多个(或单个)线程之间进行处理这些任务,单片机一般不涉及多进程。

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

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

因为单片机做这三件事情的时候,是Step by Step的,必须完成一件事情之后,再去做下一件事情,这三件事情是有先后顺序的,并且不断循环重复,如下图所示。

4c41938c-51a5-11eb-8b86-12bb97331649.png

而如果采用多线程这种方式来完成这个工作,这个过程就变得相对简单了,比如针对音乐播放器这个场景,可以设计这几个线程来处理:音乐文件读取线程,歌词文件读取线程,MV文件读取线程,音视频和歌词显示线程。

(此处只为举例描述多线程的概念,不考虑音视频编解码的复杂过程,不考虑线程同步,实际上音乐播放器的实现比此处描述更复杂)

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

4c9bb114-51a5-11eb-8b86-12bb97331649.png

如上图所示,这几个任务看上去是“同时”进行的,每个任务都只完成自己的事情,通过多线程,就可以把原本串行完成的任务改为并行完成,大大提高了工作效率。

所以,通俗地对多线程进行理解,就是把一个比较大型的任务,拆分为多个小型的任务,然后通过合理的调度方式,让这几个小型的任务“同时”运行,当这几个小型任务完成后,大型的任务也随之完成,这样可以大大提高任务的完成效率。

多线程的几种状态

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

4cda31aa-51a5-11eb-8b86-12bb97331649.png

关于这五种线程状态的描述,如下表所示:

4d28d3c8-51a5-11eb-8b86-12bb97331649.png

多线程的API函数

如上图的状态机所示,多线程可以通过调用系统提供的函数接口,在多个状态之间进行切换。这些API函数在官方提供的参考文档里面都有详细的说明描述,以下列举一些比较常用的函数接口。

4d67ac38-51a5-11eb-8b86-12bb97331649.png

上下滑动查看 API 函数

多线程的应用示例

多线程的应用示例,主要是为了验证以上的多线程API接口函数,并且通过实验现象观察多线程的运行情况,主要有以下三个示例:

示例源码下载链接:

https://github.com/embediot/rtthread_study_notes

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

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

4deffb10-51a5-11eb-8b86-12bb97331649.png

2、相同优先级线程的时间片轮转调度示例。

这个示例主要是通过动态方式创建线程1和线程2,这两个线程都是相同的优先级,并且共用一个线程入口函数,主要是通过传入不同的线程参数以区分线程1和线程2。线程2运行所占用的时间片比线程1要少,因此线程2运行的时间比较短,初始化代码如下图所示。

4e31fdee-51a5-11eb-8b86-12bb97331649.png

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

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

4e8a46f2-51a5-11eb-8b86-12bb97331649.png

多线程应用的注意事项

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

1、RT-Thread的线程调度器是抢占式的,也就是能够保证就绪队列里面,最高优先级的任务总能获得CPU的使用权,在任务设计的时候,要充分考虑好任务的优先级。

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

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

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

5、对于没有一直循环执行的线程,线程执行完毕后,资源的回收情况实际上是在空闲线程里面进行的,线程变为关闭状态后,不代表资源马上被回收。

6、系统空闲线程是最低优先级且永远为就绪状态的,空闲线程是一个死循环,永远不会被挂起,但可以被其他高优先级任务抢占,空闲线程主要执行僵尸线程的资源回收工作。

7、空闲线程也可以设置钩子函数,用来进行功耗管理,看门狗喂狗等工作。

8、通过动态方式创建的线程,需要设置好系统堆内存的大小,而通过静态方式创建的线程,线程栈和线程句柄在程序编译的时候就已经确定,不能被动态分配,也不能被释放。

9、大多数线程都是在不断循环执行的,无需进行删除,一般不推荐主动删除线程。线程运行完毕后,系统调度器将会自动把线程加入僵尸队列,资源回收工作将在空闲线程里面进行。

责任编辑:lq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    6259

    浏览量

    121839
  • 多线程
    +关注

    关注

    0

    文章

    271

    浏览量

    19718
  • RT-Thread
    +关注

    关注

    31

    文章

    1147

    浏览量

    38857

原文标题:【学习笔记】RT-Thread 多线程学习总结

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    4月25日北京站RT-Thread线下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深
    的头像 发表于 04-16 08:35 49次阅读
    4月25日北京站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深嵌入式软件工程师农晓明老师为您讲
    的头像 发表于 03-27 11:36 410次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深
    的头像 发表于 03-27 08:34 135次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    rt-thread是如何在线程运行结束识别到的呢?

    通过list_thread指令发现没有main函数,rt-thread是如何在线程运行结束识别到的呢?请各位大佬指教
    发表于 03-22 08:20

    RT-Thread Nano入门:独立看门狗(IWDT)

    本文主要介绍怎么用RT-Thread Nano实现独立看门狗IWDT驱动,创建一个喂狗线程,实现定时喂狗功能。
    的头像 发表于 11-22 11:04 766次阅读
    <b class='flag-5'>RT-Thread</b> Nano入门:独立看门狗(IWDT)

    基于rt-thread的socket通信设计

    最近再研究 rt-thread 的通信 ,想设计出 eps8266(多个) rt-thread(作为中控) 服务器的通信框架,使用的开发板是 潘多拉
    的头像 发表于 10-13 15:02 662次阅读
    基于<b class='flag-5'>rt-thread</b>的socket通信设计

    试用RT-Thread Studio(VSCode)

    想尝试RT-Thread studio (VSCode),先下载安装VSCode,再搜索RT-Thread
    的头像 发表于 10-12 10:58 536次阅读
    试用<b class='flag-5'>RT-Thread</b> Studio(VSCode)

    RT-Thread v5.0.2 发布

    RT-Thread 代码仓库地址: ●  https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本发布日志详情: ●  htt
    的头像 发表于 10-10 18:45 746次阅读
    <b class='flag-5'>RT-Thread</b> v5.0.2 发布

    rt-thread线程栈初始化参数分析

    RT-Thread线程初始化的代码内有一段初始化线程堆栈的代码
    的头像 发表于 08-14 16:50 983次阅读
    <b class='flag-5'>rt-thread</b><b class='flag-5'>线程</b>栈初始化参数分析

    RT-Thread内核对象操作API详解

    目的还是学习并熟悉RT-Thread 操作系统。
    发表于 06-02 09:48 312次阅读
    <b class='flag-5'>RT-Thread</b>内核对象操作API详解

    【经验总结】一位近10年的嵌入式开发老手,到底是如何快速学习和使用RT-Thread的?

    【经验总结】一位近10年的嵌入式开发老手,到底是如何快速学习和使用RT-Thread的?
    的头像 发表于 05-16 15:33 668次阅读
    【经验<b class='flag-5'>总结</b>】一位近10年的嵌入式开发老手,到底是如何快速<b class='flag-5'>学习</b>和使用<b class='flag-5'>RT-Thread</b>的?

    基于RT-Thread Studio学习

    前期准备:从官网下载 RT-Thread Studio,弄个账号登陆,开启rt-thread学习之旅。
    的头像 发表于 05-15 11:00 2543次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>学习</b>

    rt-thread main函数的使用和其它线程的创建问题求助?

    rt-thread main函数只是一个线程任务,如果想再创建其它线程任务,是不是在void rt_application_init(void)函数下创建其它
    发表于 05-12 15:24

    RT-Thread多线程切换最终导致线程创建失败请各位指点一下是什么原因

    我在测试rt-thread 在龙芯2k上线程切换所需的花销,我的思路是创建1000个线程,所创将的线程都存放在全局静态数组中,线程中的内容是
    发表于 04-27 10:49

    RT-Thread ssd1306驱动

    RT-Thread 驱动ssd1306
    的头像 发表于 04-21 10:08 26.4w次阅读
    <b class='flag-5'>RT-Thread</b> ssd1306驱动