RT-Thread线程管理(使用篇)


layout: post
title: “RT-Thread线程管理”
date: 2024-1-26 15:39:08 +0800
tags: RT-Thread


线程管理(使用篇)

之后会做源码分析

线程是任务的载体,是RTT中最基本的调度单位。

线程执行时的运行环境称为上下文,具体来说就是各个变量和数据,包括所有的寄存器变量、堆栈、内存信息等。

管理的特点

RT-Thread 线程管理的主要功能是对线程进行管理和调度,系统中总共存在两类线程,分别是系统线程和用户线程

这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除。

RT-Thread 的线程调度器是抢占式的,主要的工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到 CPU 的使用权。

struct rt_thread
{/* rt object */char        name[RT_NAME_MAX];                      /**< the name of thread 名字*/rt_uint8_t  type;                                   /**< type of object 类型*/rt_uint8_t  flags;                                  /**< thread's flags 标志位*/#ifdef RT_USING_MODULEvoid       *module_id;                              /**< id of application module */
#endifrt_list_t   list;                                   /**< the object list 对象列表*/rt_list_t   tlist;                                  /**< the thread list 线程列表*//* stack point and entry 栈对应的指针*/void       *sp;                                     /**< stack point 栈指针*/void       *entry;                                  /**< entry 入口函数*/void       *parameter;                              /**< parameter 参数*/void       *stack_addr;                             /**< stack address 栈的地址*/rt_uint32_t stack_size;                             /**< stack size 栈的大小*//* error code */rt_err_t    error;                                  /**< error code 线程错误代码*/rt_uint8_t  stat;                                   /**< thread status 线程状态*/
//对称多处理器, M3只有一个内核, 不会用到
#ifdef RT_USING_SMPrt_uint8_t  bind_cpu;                               /**< thread is bind to cpu */rt_uint8_t  oncpu;                                  /**< process on cpu` */rt_uint16_t scheduler_lock_nest;                    /**< scheduler lock count */rt_uint16_t cpus_lock_nest;                         /**< cpus lock count */rt_uint16_t critical_lock_nest;                     /**< critical lock count */
#endif /*RT_USING_SMP*//* priority */rt_uint8_t  current_priority;                    /**< current priority 当前的优先级*/rt_uint8_t  init_priority;                       /**< initialized priority 初始化时候的优先级(在优先级继承的时候使用)*/
#if RT_THREAD_PRIORITY_MAX > 32rt_uint8_t  number;rt_uint8_t  high_mask;
#endifrt_uint32_t number_mask;#if defined(RT_USING_EVENT)/* thread event */rt_uint32_t event_set;rt_uint8_t  event_info;
#endif#if defined(RT_USING_SIGNALS)rt_sigset_t     sig_pending;                        /**< the pending signals */rt_sigset_t     sig_mask;                           /**< the mask bits of signal */#ifndef RT_USING_SMPvoid            *sig_ret;                           /**< the return stack pointer from signal */
#endifrt_sighandler_t *sig_vectors;                       /**< vectors of signal handler */void            *si_list;                           /**< the signal infor list */
#endifrt_ubase_t  init_tick;                              /**< thread's initialized tick 线程初始化计数值*/rt_ubase_t  remaining_tick;                         /**< remaining tick 当前剩余的计数值*/struct rt_timer thread_timer;                       /**< built-in thread timer 一个内置的定时器*/void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit 退出回调函数*//* light weight process if present */
#ifdef RT_USING_LWPvoid        *lwp;
#endifrt_uint32_t user_data;                             /**< private user data beyond this thread */
};
typedef struct rt_thread *rt_thread_t;

cleanup函数指针指向的函数,会在线程退出的时候,被idle线程回调一次,执行用户设置的清理现场等工作。

成员user_data可由用户挂接一些数据信息到线程控制块中,以提供类似线程私有数据的实现

线程属性

线程状态

image-20240127164313400

优先级

最大支持 256 个线程优先级 (0~255),数值越小的优先级越高,0 为最高优先级。在一些资源比较紧张的系统中,可以根据实际情况选择只支持 8 个或 32 个优先级的系统配置

对于 ARM Cortex-M系列,普遍采用 32 个优先级。最低优先级默认分配给空闲线程使用,用户一般不使用。

时间片

每个线程都有时间片这个参数,但时间片仅对优先级相同的就绪态线程有效。

**注意: **线程里面不要有死循环, 否则低优先级任务不会吧执行到

错误码

/* RT-Thread error code definitions */
#define RT_EOK                          0               /**< There is no error */
#define RT_ERROR                        1               /**< 普通错误 */
#define RT_ETIMEOUT                     2               /**< Timed out */
#define RT_EFULL                        3               /**< 资源已满 */
#define RT_EEMPTY                       4               /**< 无资源 */
#define RT_ENOMEM                       5               /**< No memory */
#define RT_ENOSYS                       6               /**< No system */
#define RT_EBUSY                        7               /**< Busy */
#define RT_EIO                          8               /**< IO error */
#define RT_EINTR                        9               /**< Interrupted system call */
#define RT_EINVAL                       10              /**< 非法参数 */

状态切换

image-20240127165225864

image-20240127165707366

image-20240127165835227

系统线程

在RT-Thread内核中的系统线程有空闲线程和主线程。

空闲线程

系统创建的最低优先级的线程,线程状态永远为就绪态。当系统中无其他就绪线程存在时,调度器将调度到空闲线程,它通常是一个死循环,且永远不能被挂起。

空闲线程在RT-Thread也有着它的特殊用途:

线程运行完毕,系统将自动删除线程:自动执行rt_thread_exit()函数,先将该线程从系统就绪队列中删除,再将该线程的状态更改为关闭状态,不再参与系统调度,然后挂入rt_thread_defunct僵尸队列(资源未回收、处于关闭状态的线程队列)中,最后空闲线程会回收被删除线程的资源。

也提供了接口来运行用户设置的钩子函数,在空闲线程运行时会调用该钩子函数,适合钩入功耗管理、看门狗喂狗等工作。

主线程

入口函数为main_thread_entry()

回在这个线程里面初始化软件, 然后调用用户的main函数

实际操作API

线程相关的操作包括:创建/初始化、启动、运行、删除/脱离。

动态线程是系统自动从动态内存堆上分配栈空间与线程句柄(初始化 heap 之后才能使用 create 创建动态线程),静态线程是由用户分配栈空间与线程句柄。

image-20240127173904171

create和delete是动态的

init和detach是静态的

创建

/**动态* This function will create a thread object and allocate thread object memory* and stack.** @param name the name of thread, which shall be unique名字* @param entry the entry function of thread一个函数指针* @param parameter the parameter of thread enter function一个参数* @param stack_size the size of thread stack栈的大小* @param priority the priority of thread优先级* @param tick the time slice if there are same priority thread时间片** @return the created thread object*/
rt_thread_t rt_thread_create(const char *name,void (*entry)(void *parameter),void       *parameter,rt_uint32_t stack_size,rt_uint8_t  priority,rt_uint32_t tick)
/**静态* This function will initialize a thread, normally it's used to initialize a* static thread object.** @param thread the static thread object* @param name the name of thread, which shall be unique* @param entry the entry function of thread* @param parameter the parameter of thread enter function* @param stack_start the start address of thread stack* @param stack_size the size of thread stack* @param priority the priority of thread* @param tick the time slice if there are same priority thread** @return the operation status, RT_EOK on OK, -RT_ERROR on error*/
rt_err_t rt_thread_init(struct rt_thread *thread,const char       *name,void (*entry)(void *parameter),void             *parameter,void             *stack_start,rt_uint32_t       stack_size,rt_uint8_t        priority,rt_uint32_t       tick)

删除

/**动态的时候使用的函数* This function will delete a thread. The thread object will be removed from* thread queue and deleted from system object management in the idle thread.** @param thread the thread to be deleted** @return the operation status, RT_EOK on OK, -RT_ERROR on error*/
rt_err_t rt_thread_delete(rt_thread_t thread)
/**静态的时候使用的函数* This function will detach a thread. The thread object will be removed from* thread queue and detached/deleted from system object management.** @param thread the thread to be deleted** @return the operation status, RT_EOK on OK, -RT_ERROR on error*/
rt_err_t rt_thread_detach(rt_thread_t thread)

会在运行结束以后自动调用, 不建议使用

启动

/**开始可以被执行* This function will start a thread and put it to system ready queue** @param thread the thread to be started** @return the operation status, RT_EOK on OK, -RT_ERROR on error*/
rt_err_t rt_thread_startup(rt_thread_t thread)

获取当前在运行的任务句柄

/*** This function will return self thread object** @return the self thread object*/
rt_thread_t rt_thread_self(void)
{return rt_current_thread;
}

可以用于在多个任务执行同一段代码的时候区分

让出处理器

/*** This function will let current thread yield processor, and scheduler will* choose a highest thread to run. After yield processor, the current thread* is still in READY state.** @return RT_EOK*/
rt_err_t rt_thread_yield(void)

在让出CPU以后, 当前的线程依旧是ready状态, 会执行相同优先级的任务

休眠

/*** This function will let current thread sleep for some ticks.** @param tick the sleep ticks 系统的时钟数** @return RT_EOK*/
rt_err_t rt_thread_sleep(rt_tick_t tick)
/*** This function will let current thread delay for some ticks.** @param tick the delay ticks** @return RT_EOK*/
rt_err_t rt_thread_delay(rt_tick_t tick)
{return rt_thread_sleep(tick);
}
/*** This function will let current thread delay for some milliseconds.** @param ms the delay ms time使用毫秒级别延时** @return RT_EOK*/
rt_err_t rt_thread_mdelay(rt_int32_t ms)

控制

/*** This function will control thread behaviors according to control command.** @param thread the specified thread to be controlled* @param cmd the control command, which includes*  RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread;控制优先级*  RT_THREAD_CTRL_STARTUP for starting a thread;启动一个线程*  RT_THREAD_CTRL_CLOSE for delete a thread;删除一个线程*  RT_THREAD_CTRL_BIND_CPU for bind the thread to a CPU.把一个线程绑定在某一个CPU* @param arg the argument of control command** @return RT_EOK*/
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)

设置以及删除idle线程的hook函数

/*** @ingroup Hook* This function sets a hook function to idle thread loop. When the system performs* idle loop, this hook function should be invoked.** @param hook the specified hook function** @return RT_EOK: set OK*         -RT_EFULL: hook list is full** @note the hook function must be simple and never be blocked or suspend.*/
rt_err_t rt_thread_idle_sethook(void (*hook)(void))
/*** delete the idle hook on hook list** @param hook the specified hook function** @return RT_EOK: delete OK*         -RT_ENOSYS: hook was not found*/
rt_err_t rt_thread_idle_delhook(void (*hook)(void))

空闲线程是一个线程状态永远为就绪态的线程,因此设置的钩子函数必须保证空闲线程在任何时刻都不会处于挂起状态,例如 rt_thread_delay(),rt_sem_take() 等可能会导致线程挂起的函数都不能使用。

设置调度器hook函数

用户可能会想知道在一个时刻发生了什么样的线程切换,可以通过调用下面的函数接口设置一个相应的钩子函数。

/*** This function will set a hook function, which will be invoked when thread* switch happens.** @param hook the hook function, 可以获取线程来的位置以及下一个线程*/
void rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))

实际使用

void test_thread(void * parameter){int16_t i=0;while(1){rt_kprintf("test threader\n");rt_thread_mdelay(1000);if(i++>10)break;}
}int main(void)
{test_prt = rt_thread_create("test", test_thread, RT_NULL, 300, 20, 20);if(test_prt != RT_NULL){LOG_D("malloc test thread successed\n");}else{LOG_E("malloc test thread fail\n");}rt_thread_startup(test_prt);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/665296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin-集成SpringBoot+MyBatis+代码生成器

目录 一、相关版本 二、Maven因引入相关依赖 三、SpringBoot配置文件 四、代码生成工具 五、实现用户服务模块案例 1、Controller 2、Service 3、Entity 4、Mapper 5、接口测试 一、相关版本 工具版本Idea2022.3.2Springboot2.7.12MyBatis3.5.3.1MySQL8.0.28JDK1.8 …

Python详细教程

一、Python简历 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&#xff0c;相比其他语言经常使用英文关键字&#xff0c;其他语言的一些标点符号&#xff0c;它具有比其他语言更有特色语法结构。 Python 是一种解…

MySQL原理(五)事务

一、介绍&#xff1a; 1、介绍&#xff1a; 在计算机术语中&#xff0c;事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务是恢复和并发控制的基本单位。 2、事务的4大特性 原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性…

LaTeX表格:合并单元格、文字旋转90度并居中

在LaTeX表格中&#xff0c;如何使用\multirow合并单元格&#xff0c;并将单元格中的文字旋转九十度&#xff0c;并且居中呢&#xff1f; 首先引入graphicx、multirow和array包&#xff1a; \usepackage{graphicx} \usepackage{multirow} \usepackage{booktabs}然后定义一种新…

DoubleEnsemble:基于样本重加权和特征选择的金融数据分析方法

现代机器学习模型&#xff08;如深度神经网络和梯度提升决策树&#xff09;由于其提取复杂非线性模式的优越能力&#xff0c;在金融市场预测中越来越受欢迎。然而&#xff0c;由于金融数据集的信噪比非常低&#xff0c;并且是非平稳的&#xff0c;复杂的模型往往很容易过拟合。…

「递归算法」:Pow(x,n)

一、题目 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即&#xff0c;xn &#xff09;。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;1024.00000示例 2&#xff1a; 输入&#xff1a;x 2.10000, n 3 输出&#xff1a;9…

使用Arcgis对欧洲雷达高分辨率降水数据重投影

当前需要使用欧洲高分辨雷达降水数据&#xff0c;但是这个数据的投影问题非常头疼。实际的投影应该长这样&#xff08;https://gist.github.com/kmuehlbauer/645e42a53b30752230c08c20a9c964f9?permalink_comment_id2954366https://gist.github.com/kmuehlbauer/645e42a53b307…

深入了解 Ansible:全面掌握自动化 IT 环境的利器

本文以详尽的篇幅介绍了 Ansible 的方方面面&#xff0c;旨在帮助读者从入门到精通。无论您是初学者还是有一定经验的 Ansible 用户&#xff0c;都可以在本文中找到对应的内容&#xff0c;加深对 Ansible 的理解和应用。愿本文能成为您在 Ansible 自动化旅程中的良师益友&#…

故障诊断 | 一文解决,LSTM长短期记忆神经网络故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现LSTM长短期记忆神经网络故障诊断 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅

[基础IO]文件描述符{重定向/perror/磁盘结构/inode/软硬链接}

文章目录 1. 再识重定向2.浅谈perror()3.初始文件系统4.软硬链接 1. 再识重定向 图解./sf > file.txt 2>&1 1中内容拷贝给2 使得2指向file 再学一个 把file的内容传给cat cat拿到后再给file2 2.浅谈perror() open()接口调用失败返回-1,并且错误码errno被适当的设置,…

虚拟机Windows Server 2016 安装 MySQL8

目录 一、下载MySQL8 1.下载地址&#xff1a; 2.创建my.ini文件 二、安装步骤 第一步&#xff1a;命令窗口 第二步&#xff1a;切换目录 第三步&#xff1a;安装服务 第四步&#xff1a;生成临时密码 第五步&#xff1a;启动服务 第六步&#xff1a; 修改密码 三…

【服务器搭建】快速完成幻兽帕鲁服务器的搭建及部署【零基础上手】

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 教程详戳&#xff1a;不需要懂技术&#xff0c;1分钟幻兽帕鲁服…

stable diffusion学习笔记——高清修复

ai画图中通常存在以下痛点&#xff1a; 受限于本地设备的性能&#xff08;主要是显卡显存&#xff09;&#xff0c;无法跑出分辨率较高的图片。生图的时候分辨率一调大就爆显存。即便显存足够。目前主流的模型大多基于SD1.0和SD1.5&#xff0c;这些模型在训练的时候通常使用小…

【Git】01 Git介绍与安装

文章目录 一、版本控制系统二、Git三、Windows安装Git3.1 下载Git3.2 安装3.3 检查 四、Linux安装Git4.1 YUM安装4.2 源码安装 五、配置Git5.1 配置用户名和邮箱5.2 配置级别5.3 查看配置 六、总结 一、版本控制系统 版本控制系统&#xff0c;Version Control System&#xff…

大数据分析|大数据分析的三类核心技术

文献来源&#xff1a;Saggi M K, Jain S. A survey towards an integration of big data analytics to big insights for value-creation[J]. Information Processing & Management, 2018, 54(5): 758-790. 下载链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1…

2024.2.3 寒假训练记录(17)

补一下牛客&#xff0c;菜得发昏了&#xff0c;F搞了两个小时都没搞出来&#xff0c;不如去开H了 还没补完 剩下的打了atc再来 文章目录 牛客 寒假集训1A DFS搜索牛客 寒假集训1B 关鸡牛客 寒假集训1C 按闹分配牛客 寒假集训1D 数组成鸡牛客 寒假集训1E 本题又主要考察了贪心牛…

java设计模式:策略模式

在平常的开发工作中&#xff0c;经常会用到不同的设计模式&#xff0c;合理的使用设计模式&#xff0c;可以提高开发效率&#xff0c;提高代码质量&#xff0c;提高代码的可拓展性和维护性。今天来聊聊策略模式。 策略模式是一种行为型设计模式&#xff0c;运行时可以根据需求动…

(2024|ICLR reviewing,IGN,EBGAN,重建、幂等和流形紧致目标)幂等生成网络

Idempotent Generative Network 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 方法 2.1 优化目标 2.2 训练 2.3 架构和优化 4. 实验 5. 相关工作 6. 局限性 0. 摘要…

PyTorch基础-Tensors属性、Tensor的运算

PyTorch的基本概念 Tensor的基本概念 张量高于标量、向量、矩阵 标量说零维的张量&#xff0c;向量是一维的张量&#xff0c;矩阵是二维的张量 Tensor与机器学习的关系 Tensor的创建 函数功能Tensor(*size)基础构造函数Tensor(data)类似np.arrayones(*size)全1Tensorzeros(…

029 命令行传递参数

1.循环输出args字符串数组 public class D001 {public static void main(String[] args) {for (String arg : args) {System.out.println(arg);}} } 2.找打这个类的路径&#xff0c;打开cmd cmd C:\Users\Admin\IdeaProjects\JavaSE学习之路\scanner\src\com\yxm\demo 3. 编译…