RT-Thread-02-线程创建

线程

   在RT-THread中,最小任务对应的是线程,RT-Thread就是一个能对这些线程进行管理和调度的多线程操作系统。
   线程是实现任务的载体,它是RT-Thread中最基本的调度单元,描述了一个任务执行的运行环境,和这个任务所处的优先级。
   RT-Thread中,线程由三部分构成:线程代码(入口函数)、线程控制块、线程堆栈;
  • 线程代码(入口函数)包含以下两种形式:
    RT-Thread-02-线程创建_第1张图片
    RT-Thread-02-线程创建_第2张图片
  • 线程控制块
    包含用于管理线程的信息,如线程优先级、线程名称、线程状态等,也包含线程与线程之间连接用的链表结构,线程等待时间集合等
struct rt_thread;
struct rt_thread *rt_thread_t;
在rtdef.h中
/**
 * Thread structure
 */
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 */

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

    void            *sig_ret;                           /**< the return stack pointer from signal */
    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

    rt_uint32_t user_data;                             /**< private user data beyond this thread */
};
typedef struct rt_thread *rt_thread_t;

/*@}*/
  • 线程栈
    RTT中没个线程都具有独立的栈空间,在进行线程切换时,系统会将当前线程的上下文保存在线程中,当线程要恢复运行时,再从线程栈读取上下文信息,恢复线程的运行;
    线程上下文是指线程执行的环境,具体来说就是各个变量和数据包括所有寄存器变量、堆栈信息、内存信息等;
    线程栈在形式上是一段连续的内存空间,可以通过定义一个数组或者申请一段动态内存来作为线程的栈。

  • 线程创建

1-创建线程
(1)创建静态线程:
rt_err_t rt_thread_init(struct_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)2)创建动态线程:
rt_err_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)
2-启动线程
rt_err_t  rt_thread_startup(rt_thread_t thread)
通过使用这个函数将创建的线程加入到线程就绪队列,执行调度;

官方示例代码:

/* 
 * Copyright (c) 2006-2018, RT-Thread Development Team 
 * 
 * SPDX-License-Identifier: Apache-2.0 
 * 
 * Change Logs: 
 * Date           Author       Notes 
 * 2018-08-24     yangjie      the first version 
 */ 

/*
 * 程序清单:创建/删除、初始化线程
 *
 * 这个例子会创建两个线程,一个动态线程,一个静态线程。
 * 一个线程在运行完毕后自动被系统删除,另一个线程一直打印计数。
 */
#include <rtthread.h>

#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5

static rt_thread_t tid1 = RT_NULL;

/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{
    rt_uint32_t count = 0;

    while (1)
    {
        /* 线程1采用低优先级运行,一直打印计数值 */
        rt_kprintf("thread1 count: %d\n", count ++);
        rt_thread_mdelay(500);
    }
}

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
/* 线程2入口 */
static void thread2_entry(void *param)
{
    rt_uint32_t count = 0;

    /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */
    for (count = 0; count < 10 ; count++)
    {
        /* 线程2打印计数值 */
        rt_kprintf("thread2 count: %d\n", count);
    }
    rt_kprintf("thread2 exit\n");
    /* 线程2运行结束后也将自动被系统删除
    (线程控制块和线程栈依然在idle线程中释放) */
}

/* 删除线程示例的初始化 */
int thread_sample(void)
{
    /* 创建线程1,名称是thread1,入口是thread1_entry*/
    tid1 = rt_thread_create("thread1",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    
    /* 如果获得线程控制块,启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);

    /* 初始化线程2,名称是thread2,入口是thread2_entry */
    rt_thread_init(&thread2,
                   "thread2",
                   thread2_entry,
                   RT_NULL,
                   &thread2_stack[0],
                   sizeof(thread2_stack),
                   THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    rt_thread_startup(&thread2);

    return 0;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_sample, thread sample);


仿真运行结果:
RT-Thread-02-线程创建_第3张图片

你可能感兴趣的:(mcu,c++,c语言)