3. 线程删除与脱离
任务目标
在RT-Thread中,线程资源(TCB与栈)可由系统动态分配(rt_thread_create)或由用户静态定义(rt_thread_init)。本案例实现两种线程终止方式:删除(delete)与脱离(detach),并观察不同方式下线程状态与资源回收的差异。
核心概念
- rt_thread_delete:仅适用于动态创建的线程。调用后线程将从就绪队列移除并变为关闭状态,其TCB和栈内存被系统回收,之后不可再使用该线程控制块。
- rt_thread_detach:仅适用于静态初始化的线程。调用后线程变为关闭状态,但TCB和栈内存不会被释放(因由用户静态提供),线程控制块变为空闲可重新初始化。
完整代码
#include <rtthread.h>
/* 静态线程控制块与栈 */
static struct rt_thread static_thread;
static rt_uint8_t static_stack[512];
/* 动态线程控制块指针 */
static rt_thread_t dynamic_thread = RT_NULL;
/* 静态线程入口:由其他线程删除 */
static void static_entry(void *param)
{
rt_kprintf("static thread running, will be deleted by main thread\n");
while (1) {
rt_thread_mdelay(1000);
}
}
/* 动态线程入口:自我删除 */
static void dynamic_entry(void *param)
{
rt_kprintf("dynamic thread running, will delete itself\n");
rt_thread_delay(10); /* 等待主线程完成创建操作 */
rt_thread_delete(dynamic_thread); /* 自我删除 */
}
/* 主线程(在main线程中执行) */
int main(void)
{
rt_err_t result;
/* 1. 创建动态线程 */
dynamic_thread = rt_thread_create("dyn",
dynamic_entry,
RT_NULL,
1024,
20,
10);
if (dynamic_thread != RT_NULL) {
rt_thread_startup(dynamic_thread);
}
/* 2. 初始化静态线程 */
result = rt_thread_init(&static_thread,
"stat",
static_entry,
RT_NULL,
&static_stack[0],
sizeof(static_stack),
21,
10);
if (result == RT_EOK) {
rt_thread_startup(&static_thread);
}
/* 3. 等待动态线程自我删除完成 */
rt_thread_mdelay(100);
/* 4. 删除静态线程 */
rt_thread_delete(&static_thread); /* 注意:静态线程应使用detach,此处演示错误用法 */
return 0;
}
运行与观察
- 将代码复制到RT-Thread工程的
main.c中,编译并烧录。 - 打开串口终端,观察输出顺序。
预期输出(串口):
dynamic thread running, will delete itself
static thread running, will be deleted by main thread
验证要点
- 动态线程自我删除:调用
rt_thread_delete(dynamic_thread)后,该线程不再运行,其TCB和栈内存被系统回收。可通过再次调用rt_thread_create创建同名线程验证内存可复用。 - 静态线程错误删除:对静态线程调用
rt_thread_delete会触发断言(rt_assert)或返回错误码,因为静态线程的TCB不在动态内存池中。正确做法是调用rt_thread_detach(&static_thread)。
修正建议
将主线程中删除静态线程的代码改为:
rt_thread_detach(&static_thread); /* 静态线程使用detach */
修改后重新编译运行,静态线程将被正确脱离,系统不再报错。
状态变化说明
- 删除(delete):线程状态 →
RT_CLOSE,资源(TCB+栈)由系统释放。 - 脱离(detach):线程状态 →
RT_CLOSE,资源(TCB+栈)由用户保留,可重新rt_thread_init复用。