RT-Thread 线程管理(学习一)

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

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

特点

RTT系统中总共存在两类线程,分别是系统线程和用户线程,系统线程由内核创建,用户线程由应用程序创建,这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会从对象容器中删除。

RTT的线程调度器是抢占式的,主要的工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到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_MODULE
    void       *module_id;                              /**< id of application module */
#endif

    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 */
    rt_uint32_t stack_size;                             /**< stack size */

    /* error code */
    rt_err_t    error;                                  /**< error code */

    rt_uint8_t  stat;                                   /**< thread status */

#ifdef RT_USING_SMP
    rt_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 > 32
    rt_uint8_t  number;
    rt_uint8_t  high_mask;
#endif
    rt_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_SMP //对称多处理器,Cortex-M3是单核的
    void            *sig_ret;                           /**< the return stack pointer from signal */
#endif
    rt_sighandler_t *sig_vectors;                       /**< vectors of signal handler */
    void            *si_list;                           /**< the signal infor list */
#endif

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

    /* light weight process if present */
#ifdef RT_USING_LWP
    void        *lwp;
#endif

线程与线程之间用链接结构进行连接。

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

线程属性

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

线程状态
stat

  • 初始状态:当线程刚开始创建还没开始运行时就处于就绪状态;在初始状态下,线程不参与调度,定义为RT_THREAD_INIT。
  • 就绪状态:在就绪状态下,线程按照优先级排队,等待被执行;一旦当前线程运行完毕让出处理器,操作系统会马上寻找最高优先级的就绪态线程运行,定义为RT_THREAD_READY。
  • 运行状态:线程当前正在运行。在单核系统中,只有rt_thread_self()函数返回的线程处于运行状态。多核系统中,可能就不止一个。定义为RT_THREAD_RUNNING。
  • 挂起状态:也称阻塞态。它可能因为资源不可用而挂起等待,或线程主动延时一段时间而挂起。在挂起状态下,线程不参与调度。RT_THREAD_SUSPEND。
  • 关闭状态:当线程运行结束时处于关闭状态。关闭状态的线程不参与线程的调度。RT_THREAD_CLOSE。

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

对于ARM Cortex-M系列,普遍采用32个优先级。
最低优先级默认分配给空闲线程使用,用户一般不使用。
在系统中,当有比当前线程优先级更高的线程就绪时,当前线程立刻被换出,高优先级线程抢占处理器运行。

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

注意
作为一个实时系统,一个优先级明确的实时系统,如果一个线程中的程序陷入了死循环操作,那么比它优先级的线程都将不能够得到执行。
因此,线程中不能陷入死循环操作,必须要有让出CPU使用权的操作,如循环中调用延时函数或者主动挂起。

线程状态之间切换

RT-Thread 线程管理(学习一)_第1张图片

你可能感兴趣的:(RT-Thread,学习,RT-Thread)