RT-Thread线程-创建线程

在RT-Thread实时操作系统中,创建线程可以通过以下两种方式实现:

动态创建线程

动态创建线程是指在运行时根据需要动态分配线程所需的内存资源(控制块和堆栈)。这种方式适用于需要在程序运行过程中灵活创建和销毁线程的场景。

API函数: rt_thread_create()

函数原型:

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)

参数说明:

  • name:线程的名字,用于标识和调试。
  • entry:线程的入口函数,线程开始执行时调用的第一个函数。
  • parameter:传递给线程入口函数的参数,用于传递线程私有数据。
  • stack_size:线程堆栈大小,单位为字节。
  • priority:线程优先级,取值范围通常为0至系统最大优先级数(如255)。
  • tick:线程的时间片数,用于时间片轮转调度。对于大多数应用,可以设置为0,表示不使用时间片轮转。

返回值:

  • 成功创建并初始化线程后,返回指向新创建线程的指针。
  • 创建失败(如内存不足等原因),返回RT_NULL

示例代码:

static void my_thread_entry(void *arg)
{
    // 线程执行的代码...
}

int main(void)
{
    rt_thread_t my_thread;
    my_thread = rt_thread_create("my_thread",
                                 my_thread_entry, NULL, /* 入口函数与参数 */
                                 2048,                   /* 堆栈大小 */
                                 20,                     /* 优先级 */
                                 0);                     /* 时间片数 */
    if (my_thread != RT_NULL)
    {
        rt_thread_startup(my_thread);  // 启动线程
    }
    else
    {
        // 创建失败,处理错误...
    }
    return 0;

}

静态创建线程

静态创建线程是指在编译阶段就为线程预留好控制块和堆栈空间,通常在全局或静态变量区分配。这种方式适用于资源受限或对实时性要求较高的场景,可以减少运行时的内存分配开销。

API函数: rt_thread_init()

函数原型:

 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)

参数说明:

  • thread:指向已定义的线程控制块的指针。
  • name:线程的名字,用于标识和调试。
  • entry:线程的入口函数,线程开始执行时调用的第一个函数。
  • parameter:传递给线程入口函数的参数,用于传递线程私有数据。
  • stack_start:线程堆栈的起始地址,指向之前定义的堆栈数组。
  • stack_size:线程堆栈大小,单位为字节。
  • priority:线程优先级,取值范围通常为0至系统最大优先级数(如255)。
  • tick:线程的时间片数,用于时间片轮转调度。对于大多数应用,可以设置为0,表示不使用时间片轮转。

返回值:

  • RT_EOK:表示操作成功。这是一个常量,通常定义为0或一个特定的正数,表示没有错误发生。
  • 创建失败,返回负数值:通常代表各种具体的错误代码(RT_ETIMEOUTRT_EBUSY等),每个数值对应一种特定的错误情况。

示例代码:

 #include <rtthread.h>
    
    /* 定义线程控制块 */
    static struct rt_thread my_thread;
    /* 定义堆栈空间 */
    static rt_uint8_t my_thread_stack[2048];
    
    static void my_thread_entry(void *arg)
    {
        // 线程执行的代码...
    }
    
    int main(void)
    {
        /* 初始化线程 */
        rt_thread_init(&my_thread, "my_thread", /* 线程名 */
                       my_thread_entry, NULL,     /* 入口函数与参数 */
                       &my_thread_stack[0],       /* 堆栈起始地址 */
                       sizeof(my_thread_stack),    /* 堆栈大小 */
                       20,                        /* 优先级 */
                       0);                        /* 时间片数 */
        rt_thread_startup(&my_thread);  // 启动线程
        return 0;
    }

无论是动态创建还是静态创建线程,创建成功后均需通过rt_thread_startup()函数启动线程,使其进入就绪态并可能立即投入运行。创建失败时,应妥善处理错误情况,避免资源泄漏或系统异常。

线程控制块(TCB)

线程控制块(Thread Control Block, TCB)是操作系统中用于管理和控制线程的数据结构。它是线程在系统中的核心表示,存储了线程的关键属性、状态信息以及与线程生命周期管理相关的数据。以下是对线程控制块(TCB)的详细介绍:

作用与目的

线程标识与状态记录:TCB作为线程的唯一标识,记录线程的唯一标识符(线程ID)和当前状态(如就绪、运行、挂起、阻塞、结束等),使得操作系统能够准确跟踪和控制各个线程的执行情况。

调度信息:TCB包含线程的优先级、时间片、调度策略等信息,这些数据是操作系统调度器进行线程调度决策的依据,确保线程能在适当的时机获得CPU资源。

上下文保存与切换:TCB存储了线程执行时的CPU寄存器状态(如程序计数器PC、通用寄存器、状态寄存器等),当发生线程上下文切换时,这些信息会被保存到当前线程的TCB中,同时从即将运行的线程TCB中加载相应的寄存器状态,从而实现线程执行现场的切换。

资源关联:TCB关联了线程使用的系统资源,如线程私有堆栈、共享资源的锁定状态、等待队列链接等,这些信息对于线程间的同步与通信、资源分配与回收至关重要。源码

  /* 线程控制块 */
    struct rt_thread
    {
        /* rt 对象 */
        char        name[RT_NAME_MAX];     /* 线程名称 */
        rt_uint8_t  type;                   /* 对象类型 */
        rt_uint8_t  flags;                  /* 标志位 */
    
        rt_list_t   list;                   /* 对象列表 */
        rt_list_t   tlist;                  /* 线程列表 */
    
        /* 栈指针与入口指针 */
        void       *sp;                      /* 栈指针 */
        void       *entry;                   /* 入口函数指针 */
        void       *parameter;              /* 参数 */
        void       *stack_addr;             /* 栈地址指针 */
        rt_uint32_t stack_size;            /* 栈大小 */
    
        /* 错误代码 */
        rt_err_t    error;                  /* 线程错误代码 */
        rt_uint8_t  stat;                   /* 线程状态 */
    
        /* 优先级 */
        rt_uint8_t  current_priority;    /* 当前优先级 */
        rt_uint8_t  init_priority;        /* 初始优先级 */
        rt_uint32_t number_mask;
    
        ......
    
        rt_ubase_t  init_tick;               /* 线程初始化计数值 */
        rt_ubase_t  remaining_tick;         /* 线程剩余计数值 */
    
        struct rt_timer thread_timer;      /* 内置线程定时器 */
    
        void (*cleanup)(struct rt_thread *tid);  /* 线程退出清除函数 */
        rt_uint32_t user_data;                      /* 用户数据 */
    };

动态/静态创建线程区别

动态创建线程和静态创建线程在RT-Thread实时操作系统中有以下几个主要区别:

内存分配时机与方式:

  • 动态创建:在线程创建时(运行时),通过内存分配函数(如rt_malloc())从动态内存堆中动态分配线程控制块和堆栈空间。创建的线程可以在程序运行过程中随时创建、启动、销毁,具有较高的灵活性。
  • 静态创建:在编译阶段就已经为线程预留好控制块和堆栈空间,通常在全局或静态变量区静态分配。这样可以避免运行时的内存分配操作,适合资源有限或对实时性要求高的场景。

内存管理成本与效率:

  • 动态创建:由于涉及到运行时的内存分配和释放,可能存在一定的内存管理开销,如查找可用内存、分配内存块、维护内存管理数据结构等。尤其是在内存碎片严重或内存池不足时,分配效率可能会下降。
  • 静态创建:预先分配好的内存无需运行时管理,因此省去了动态内存分配的开销,创建和销毁线程的效率通常更高。但如果静态分配的资源过多,可能会增加程序的总体内存占用,特别是在资源有限的嵌入式系统中需要注意。

资源限制与可扩展性:

  • 动态创建:理论上可以创建任意数量的线程(受总内存大小限制),适应性强,适用于需要根据运行时条件动态调整线程数量的应用。
  • 静态创建:线程数量受到编译时预定义的静态资源限制,扩展性相对较差,适用于线程数量固定或变化范围较小的场景。

内存泄漏风险:

  • 动态创建:若忘记在适当时候调用rt_thread_delete()删除动态创建的线程,可能导致内存泄漏。需要确保在程序退出或线程不再需要时正确释放资源。
  • 静态创建:由于使用的是全局或静态内存,不存在忘记释放的问题。但是,如果静态线程的生命周期管理不当,可能导致资源无法重用或浪费。

编程复杂度与可移植性:

  • 动态创建:编程相对简单,只需调用rt_thread_create()即可创建线程,不需要手动管理线程控制块和堆栈。代码更易于理解和维护,且在不同平台或系统配置下移植性较好。
  • 静态创建:需要手动定义线程控制块和堆栈,初始化时需要提供堆栈起始地址。代码稍显复杂,但对特定硬件平台的资源利用可能更为精细。

总结来说,动态创建线程和静态创建线程的主要区别在于内存分配的时间、方式、效率、可扩展性、资源管理风险以及编程复杂度。选择哪种方式取决于具体的应用需求、系统资源状况以及对实时性和代码管理的要求。在实际开发中,可以根据项目特点灵活运用这两种创建方式。

创建线程的代码例程已上传,需要获取自行获取
https://download.csdn.net/download/weixin_42530814/89218918?spm=1001.2014.3001.5501

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值