RT-Thread之线程管理(线程的删除及线程的属性)

举报
yd_274589494 发表于 2024/05/26 08:21:06 2024/05/26
【摘要】 @TOC 前言本篇文章我们来讲解RT-Thread中线程的属性和调度算法等内容。 一、线程的删除rt_thread_detach() 函数:功能:rt_thread_detach() 函数用于将一个线程从系统中分离(detach),使得该线程不再被调度执行。但是,线程的资源(如线程控制块、栈等)不会被释放,可以通过 rt_thread_attach() 函数重新将其附加到系统中。参数:thr...

@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中的队列。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。