RTT(RT-Thread)线程管理(1.2W字详细讲解)

RT-Thread是一个支持多任务的操作系统,通过线程实现任务调度。线程具有独立栈,状态包括就绪、运行、挂起等,优先级0为最高。线程管理包括创建、删除、初始化和脱离。调度器是抢占式的,高优先级线程能立即执行。线程控制块存储线程信息,上下文在切换时保存和恢复。文章还介绍了线程创建、删除函数,以及线程辅助函数如睡眠、让出处理器等。

目录

RTT线程管理

 线程管理特点

线程工作机制

线程控制块

线程属性

线程状态之间切换

线程相关操作

创建和删除线程

创建线程

删除线程

动态创建线程实例

启动线程

初始化和脱离线程

初始化线程

脱离线程

静态创建线程实例 

线程辅助函数

获得当前线程

让出处理器资源

线程睡眠

控制线程函数

设置和删除idle线程hook函数

设置钩子函数

删除钩子函数

设置调度器hook函数

线程调度器hook函数实例


 RTT线程管理

        RT-Thread是支持多任务的操作系统,多任务是通过多线程的方式实现。线程是任务的载体,是RTT中最基本的调度单位。

        线程在运行的时候,它自己会认为独占CPU运行

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

 线程管理特点

        RT-Thread 线程管理的主要功能是对线程进行管理和调度,系统中总共存在两类线程,分别是系统线程用户线程,系统线程是由 RT-Thread 内核创建的线程,用户线程是由应用程序创建的线程,这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除。

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

        当调度器调度线程切换时,先将当前线程上下文保存起来,当再切回到这个线程时,线程调度器将该线程的上下文信息恢复。(我们在切换完以后,当再次回到之前执行的线程时候,要从被打断的地方重新开始执行,所以我们要将线程上下文先保存起来)线程再被调度之前,我们要保存现场,保存完现场之后再执行高优先级的线程,在我们再调度回来的时候,再恢复现场。但这些不需要我们应用层手动来做。

线程工作机制

线程控制块

        线程控制块由结构体 struct rt_thread 表示,线程控制块是操作系统用于管理线程的一个数据结构,它会存放线程的一些信息,例如优先级、线程名称、线程状态等,也包含线程与线程之间连接用的链表结构(内核在管理多个线程的时候,将描述每个线程的结构体采用一个列表的形式来管理起来,为了方便内核后期来查找和管理),线程等待事件集合等。

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 */

   rt_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 point 栈地址指针*/
   rt_uint32_t stack_size;      /**< stack size */

   /* error code */
     rt_err_t    error;                   /**< error code */
     rt_uint8_t  stat;                    /**< thread status 线程状态*/

    /* priority */
    rt_uint8_t  current_priority;        /**< current priority */
    rt_uint8_t  init_priority;           /**< initialized priority */

    rt_uint32_t number_mask;

    ...

    rt_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 */

    rt_uint32_t user_data;                          /**< private user data beyond this thread */
};

其中有个对称多核处理器的功能,如果属于cortex-M系列的处理器,因为是单核,所以不使用对称多核处理器,但cortex-A系统多核支持

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

线程属性

  • 线程栈

        RT-Thread 线程具有独立的栈,当进行线程切换时,会将当前线程的上下文存在栈中,当线程要恢复运行时,再从栈中读取上下文信息,进行恢复。

  • 线程状态

可以通过查看线程控制块结构体的flags成员来判断当前线程所处状态

  • 线程优先级

        RT-Thread 最大支持 256 个线程优先级 (0~255),数值越小的优先级越高,0 为最高优先级。在一些资源比较紧张的系统中,可以根据实际情况选择只支持 8 个或 32 个优先级的系统配置;对于 ARM Cortex-M系列,普遍采用 32 个优先级。最低优先级默认分配给空闲线程使用,用户一般不使用。在系统中,当有比当前线程优先级更高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处理器运行

  • 时间片

每个线程都有时间片这个参数,但时间片仅对优先级相同的就绪态线程有效。(如果多个线程的优先级相同,对于同一优先级的线程,调度的时候根据时间片进行调度,即每个线程调度一段时间然后切换另一个线程来调度执行)

注意:

        作为一个实时系统,一个优先级明确的实时系统,如果一个线程中的程序陷入了死循环操作,那么比它优先级低的线程都将不能够得到执行。所以在实时操作系统中必须注意的一点就是:线程中不能陷入死循环操作,必须要有让出 CPU使用权的动作循环中调用延时函数或者主动挂起(两种方法都能使线程处于挂起态,挂起态是不参加线程调度的,这时我们的系统就可以调度其它线程去执行)

线程状态之间切换

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

竹烟淮雨(408考研ing)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值