RT-Thread之线程管理(线程的删除及线程的属性)
@TOC
前言
本篇文章我们来讲解RT-Thread中线程的属性和调度算法等内容。
一、线程的删除
rt_thread_detach() 函数:
功能:rt_thread_detach() 函数用于将一个线程从系统中分离(detach),使得该线程不再被调度执行。但是,线程的资源(如线程控制块、栈等)不会被释放,可以通过 rt_thread_attach() 函数重新将其附加到系统中。
参数:
thread:要分离的线程的线程控制块指针。
返回值:
如果成功,返回 RT_EOK;
如果失败,返回错误码。
使用方法:
适用于使用 rt_thread_init() 创建的线程。
当你需要保留线程资源但不希望该线程继续执行时,可以使用该函数。
示例代码:
#include <rtthread.h>
static struct rt_thread thread; // 定义线程控制块
static char thread_stack[512]; // 定义线程栈
void thread_entry(void* parameter)
{
// 线程的入口函数,实现线程的具体逻辑
}
int main(void)
{
// 初始化线程
rt_thread_init(&thread, "my_thread", thread_entry, NULL, thread_stack, sizeof(thread_stack), 10, 20);
// 启动线程
rt_thread_startup(&thread);
// 等待线程运行一段时间后分离
rt_thread_delay(RT_TICK_PER_SECOND * 5);
// 分离线程
rt_err_t result = rt_thread_detach(&thread);
if (result == RT_EOK) {
rt_kprintf("Thread detached successfully.\n");
} else {
rt_kprintf("Failed to detach thread. Error code: %d\n", result);
}
return 0;
}
rt_thread_delete() 函数:
功能:rt_thread_delete() 函数用于彻底删除一个线程,释放该线程占用的资源,包括线程控制块、栈等。
参数:
thread:要删除的线程的线程控制块指针。
返回值:
如果成功,返回 RT_EOK;
如果失败,返回错误码。
使用方法:
适用于使用 rt_thread_create() 创建的线程。
当你需要完全释放线程资源并将其从系统中移除时,可以使用该函数。
示例代码:
#include <rtthread.h>
void thread_entry(void* parameter)
{
// 线程的入口函数,实现线程的具体逻辑
}
int main(void)
{
rt_thread_t thread;
// 创建线程
thread = rt_thread_create("my_thread", thread_entry, NULL, 512, 10, 20);
// 启动线程
rt_thread_startup(thread);
// 等待线程运行一段时间后删除
rt_thread_delay(RT_TICK_PER_SECOND * 5);
// 删除线程
rt_err_t result = rt_thread_delete(thread);
if (result == RT_EOK) {
rt_kprintf("Thread deleted successfully.\n");
} else {
rt_kprintf("Failed to delete thread. Error code: %d\n", result);
}
return 0;
}
二、线程优先级
线程优先级(Priority):
定义:每个线程都有一个优先级,用来表示线程在调度时的重要程度。优先级越高的线程,在竞争执行资源时更有可能被调度执行。
范围:通常情况下,RT-Thread 中线程优先级最大范围是 0 到 255。255 是最低优先级,0是最高优先级。
在一些资源比较紧张的系统中,可以根据实际情况设置优先级,比如 ARM Cortex-M系列,通常采用 32 个优先级
由 rtconfig.h 中定义的 RT_THREAD_PRIORITY_MAX 宏指定优先级范围。
设置:在创建线程时,可以指定线程的优先级。优先级高的线程会在优先级低的线程之前被调度执行。
使用:当多个线程同时处于就绪状态时,调度器会选择优先级最高的线程执行,直到它放弃 CPU 控制权或阻塞等待事件发生。
三、时间片
定义:时间片是指每个线程被分配到的连续 CPU 执行时间。时间片的大小决定了一个线程在 CPU 上执行的时间长度。
使用:时间片的大小影响着系统的响应速度和实时性。较小的时间片可以提高任务的切换频率,增强系统响应能力,但也会增加调度器的开销。
一个时间片的大小通常是1ms:
在rtconfig.h中可以使用RT_TICK_PER_SECOND这个宏来修改时间片的大小。
假设有 2 个优先级相同的就绪态线程 A 与 B。
A 线程的时间片设置为 10,B 线程的时间片设置为 5。
且当系统中不存在比 A、B 优先级高的就绪态线程时,系统会在 A、B 线程间来回切换执行。
在 t1 至 t1+5 这 5 个时间片,线程 B 运行
在 t1+5 至 t1+15 这 10 个时间片,线程 A 运行
四、优先级实验
以下是一个简单的 RT-Thread 示例代码,用于演示线程优先级的实验:
#include <rtthread.h>
#include <rtdevice.h>
#define THREAD_STACK_SIZE 512
#define THREAD_PRIORITY_LOW 10
#define THREAD_PRIORITY_MEDIUM 20
#define THREAD_PRIORITY_HIGH 30
static rt_thread_t thread_low;
static rt_thread_t thread_medium;
static rt_thread_t thread_high;
static void thread_entry(void *parameter) {
rt_uint32_t count = 0;
while (1) {
rt_kprintf("%s count: %d\n", (char *)parameter, count++);
rt_thread_mdelay(1000);
}
}
int priority_experiment_init(void) {
/* 创建低优先级线程 */
thread_low = rt_thread_create("low",
thread_entry,
"Low Priority Thread",
THREAD_STACK_SIZE,
THREAD_PRIORITY_LOW,
20);
if (thread_low != RT_NULL) {
rt_thread_startup(thread_low);
}
/* 创建中优先级线程 */
thread_medium = rt_thread_create("medium",
thread_entry,
"Medium Priority Thread",
THREAD_STACK_SIZE,
THREAD_PRIORITY_MEDIUM,
20);
if (thread_medium != RT_NULL) {
rt_thread_startup(thread_medium);
}
/* 创建高优先级线程 */
thread_high = rt_thread_create("high",
thread_entry,
"High Priority Thread",
THREAD_STACK_SIZE,
THREAD_PRIORITY_HIGH,
20);
if (thread_high != RT_NULL) {
rt_thread_startup(thread_high);
}
return 0;
}
/* 在 main 函数中调用 priority_experiment_init() */
int main(void) {
rt_thread_delay(500);
priority_experiment_init();
return 0;
}
五、Delay函数
在 RT-Thread 实时操作系统中,提供了多种延时函数来帮助开发者控制线程的执行。这些延时函数各有其用途和特点,主要包括 rt_thread_delay(), rt_thread_mdelay(), 和 rt_hw_us_delay()。下面将逐一介绍这些函数的功能和使用场景:
rt_thread_delay():
rt_thread_delay() 是 RT-Thread 中最常用的延时函数之一,它的参数是以系统时钟节拍(tick)为单位。这个函数会将当前线程挂起指定的时钟节拍数。在这段时间内,调度器不会分配 CPU 时间给当前线程,从而让出处理器给其他的线程或者进程。
函数原型:
rt_err_t rt_thread_delay(rt_tick_t tick);
参数说明:
tick: 延时的时钟节拍数。1 tick 的时间长度取决于 RT-Thread 的时钟配置(通常是 1ms 或 10ms)。
用途:
主要用于线程同步或者简单的时间控制,尤其在需要释放 CPU 给其他线程执行时非常有用。
rt_thread_mdelay():
rt_thread_mdelay() 是一个以毫秒为单位的延时函数,它内部转换毫秒数为时钟节拍后,调用 rt_thread_delay() 实现实际的延时。这个函数提供了更直观的以时间(毫秒)为单位的延时方式。
函数原型:
void rt_thread_mdelay(rt_int32_t ms);
参数说明:
ms: 延时的毫秒数。
用途:
用于需要毫秒级延时的场合,比如在设备驱动中延时等待硬件状态改变。
rt_hw_us_delay():
rt_hw_us_delay() 通常是用于微秒级别的延时,并且它通常是在硬件抽象层(HAL)中实现的,有些情况下也可能直接在 BSP(板级支持包)中实现。这个函数的实现通常依赖于硬件的定时器或者特定的延时循环,因此它可以在非常短的时间内提供准确的延时。
函数原型:
void rt_hw_us_delay(rt_uint32_t us);
us: 延时的微秒数。
用途:
主要用于需要非常短暂且精确的延时,常见于硬件驱动程序中,比如在初始化某些外设或者在与外设通信时精确控制时间间隔。
总结
使用 rt_thread_delay() 和 rt_thread_mdelay() 会导致当前线程挂起,让出 CPU 资源给其他线程,这对于多线程环境下的任务调度非常有益。
使用 rt_hw_us_delay() 通常不会引起线程调度,因为它是在极短的时间内完成的,适合于需要极高时间精度的场合。
总结
本篇文章就讲解到这里,下篇文章我们来讲解RT-Thread中的队列。
- 点赞
- 收藏
- 关注作者
评论(0)