[嵌入式系统-258]:创建一个新的线程时,需要为线程分配栈空间和线程控制块PCB, RT-Thread是如何为他们分配内存空间的?
在 RT-Thread 中,为线程分配栈空间和线程控制块(TCB)的方式取决于你选择的线程创建方法。RT-Thread 提供了动态和静态两种创建方式,它们在内存分配策略上有着本质的区别。
🚀 动态创建:从系统堆(Heap)分配
当你使用rt_thread_create()函数创建线程时,系统会自动从系统堆(Heap)中为线程控制块和栈空间分配内存。
这个过程可以分解为以下步骤:
- 分配 TCB 内存:系统首先调用内存分配函数(如
rt_malloc),从堆中申请一块足够容纳线程控制块(struct rt_thread)的内存。 - 分配栈内存:紧接着,系统会根据你在创建函数中指定的
stack_size参数,再次从堆中申请一块相应大小的内存,作为该线程的私有栈空间。 - 初始化:内存分配成功后,内核会对线程控制块和栈空间进行初始化,然后将线程加入到调度器中。
- 优点:使用简单灵活,可以在运行时随时创建和销毁线程。
- 缺点:依赖系统堆的配置,频繁创建和删除不同大小的线程可能会产生内存碎片。
🛠️ 静态创建:由用户预定义内存
当你使用rt_thread_init()函数初始化线程时,线程控制块和栈空间的内存都需要由开发者在代码中预先定义好。
这个过程如下:
- 定义 TCB 变量:你需要先定义一个
struct rt_thread类型的变量。 - 定义栈数组:同时,你需要定义一个足够大的数组(通常是
rt_uint8_t类型)来作为线程的栈空间。 - 传入地址:最后,在调用
rt_thread_init()时,将你定义的 TCB 变量的地址和栈数组的首地址作为参数传入。
这些预定义的变量和数组通常位于内存的 .bss 段 或 .data 段(即全局/静态存储区),它们的内存是在编译链接时就确定好的,不占用运行时的堆空间。
- 优点:内存分配稳定可靠,无碎片问题,实时性更好。
- 缺点:不够灵活,线程的数量和栈大小在编译时就已固定。
总结对比
下表清晰地展示了两种方式的内存分配来源:
表格
| 创建方式 | 函数接口 | 线程控制块 (TCB) 来源 | 线程栈 (Stack) 来源 |
|---|---|---|---|
| 动态创建 | rt_thread_create | 系统堆 (Heap) | 系统堆 (Heap) |
| 静态创建 | rt_thread_init | 用户预定义变量(全局/静态区) | 用户预定义数组(全局/静态区) |
