RT-Thread-快速入门-1-任务与线程

任务与线程

在这里插入图片描述


阅读须知

在这里插入图片描述


  • 为什么从任务与线程开始讲起 ?
  • 先让大家确定相关工具能否正常运行,然后通过历程先了解大概的开发流程,我们自上而下地学习,循序渐进地快速地将整个开发流程先过一遍;
  • 对嵌入式有意愿深入了解的可以关注Leon的另一个栏目,是在此基础上深入地补充了一些关注优化和实际开发需求的内容;

定义与作用

定义

  • 在RT-Thread和许多其他操作系统中,任务和线程基本上是同一个概念
  • 通常用来指代操作系统中的一个独立执行流。
  • 一个任务或线程可以认为是程序执行的一个路径,它拥有自己的寄存器上下文、堆栈空间和优先级等属性。
  • 独立性:每个任务或线程都是独立的执行单元,拥有自己的程序计数器、堆栈和一组寄存器等。
  • 并发性:多个任务或线程可以并发执行,具体的并发行为取决于操作系统的调度策略和任务的优先级。
  • 创建和控制:在RT-Thread中,任务通过特定的API函数创建和控制,如启动、挂起、继续和删除等。
  • 同步和通信:任务间可以通过信号量、消息队列、事件标志等机制进行同步和通信。

目的

  1. 并发执行:允许多个任务或线程在单个处理器上并发执行,提高系统的资源利用率和响应速度。
  2. 实时调度:确保实时任务能够在规定的时间内得到响应和处理,满足实时性要求。
  3. 资源管理:有效管理CPU、内存等资源,确保任务或线程正常运行,避免资源冲突和死锁。
  4. 同步与通信:提供机制使得不同的任务或线程之间能够协调运行,通过信号量、消息队列、事件标志等进行同步和通信。

关系:

  1. 任务与线程:在RT-Thread中,任务通常指的是线程,它们被用来指代系统中的一个独立执行流。线程是操作系统能够进行调度的最小单位。
  2. 优先级:每个任务或线程都有自己的优先级,操作系统根据这些优先级来决定哪个任务或线程应该获得CPU的控制权。优先级更高的任务在竞争资源时会被优先考虑。
  3. 调度策略:RT-Thread通常使用优先级调度策略,确保高优先级的任务能够优先运行。此外,还可以支持时间片轮转等调度策略,以确保任务公平地分享CPU时间。

原理:

  1. 任务状态:每个任务或线程在其生命周期内可能会处于不同的状态,如就绪、运行、阻塞、挂起等。操作系统根据任务的状态和优先级来进行调度。
  2. 上下文切换:当操作系统决定切换当前运行的任务时,它会进行上下文切换,保存当前任务的状态(如CPU寄存器)并加载新任务的状态,以此来实现任务之间的切换。
  3. 同步机制:提供了多种同步机制,如互斥锁、信号量、事件标志等,以帮助任务或线程间的协调和数据一致性。
  4. 通信机制:通过消息队列、邮箱等通信机制,任务可以交换信息,这对于分离任务逻辑和协调任务行为非常重要。


举例-通俗

需要知道的概念

  • 一个人工作一晚上,或者工作一天,或者一直工作下去,他的整个工作过程,叫做进程
  • 一个进程可以看作是很多线程组成,就是把整个工作过程拆成很多个工作片段;
  • 一会干这个,一会干那个,这叫线程切换
  • 我们工作过程是为了完成几个工作内容,这叫做几个任务

以我的工作为例

  • 我是开发板 -> 我是 Leon,一个普通的全栈工程师,今天导师来了需求,期望我能把网页前端按照需求美化一下 | 学弟希望我能写个代码规范方便管理代码 | MAMA-智能控制系统催进度让我完成通信协议
  • 来了几个任务 -> 我总结一下,我分别有三个任务,今天晚上要完成: 硬件通信协议 | 网页美化 | 代码规范指定 ; 一个晚上 我很可能做不完任务
  • 我分析了一下,活太多,可能干不完 -> 硬件通信协议需要边测试边修改,测试要等一阵子才知道结果;网页美化刷新页面就知道修改结果;而代码规范需要和学弟一边qq讨论一边制定 -> 也就是说,我有三个任务,如果我在制定代码规范时一直等着学弟回复,或者说硬件通信调试时我也等着调试结果,这样效率很低,我肯定今晚做不完任务 -> 这种方式效率太低,完不成任务
  • 我再分析一下,我换种工作方式,能干完了 -> 如果我在硬件通信调试时我不等着调试结果中途去改网页美化,然后顺便和学弟讨论一下,讨论后再去调试一下通信协议,我把等待的时间用来做事情 -> 这样就很可能能完成任务了
  • 简单来说 -> 是不是我有些任务中途需要等一段时间才能做,我在这段等待的时间中去做其它事情来提升我的效率 -> 这就是我们提出 任务与线程的原因
  • 再简单一点 -> 嵌入式板子执行多个任务的过程中,穿插进行任务的工作,通过合适的调度来提升效率 -> 这就是 多线程


示例

实现

  • 基于stm32-f103-c8t6 RT-Thread
  • 三个线程,分别输出三句话对应所在线程序号,输出完语句后又延时3s

  • 一号任务的执行期间需要等待,如果说,它的等待期间不允许嵌入式板进行其他任务的工作,那么按照这个道理,几个语句不可能同时输出
  • 但是我们通过代码运行和观察可知,他们在很短的时间间隙内同时输出,说明这种方法是能利用时间间隔在任务之间交替工作,能提升工作效率

示例

在这里插入图片描述


#include <rtthread.h>

#define THREAD_STACK_SIZE 512
#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 5

// 线程控制块
static struct rt_thread thread1;
static struct rt_thread thread2;
static struct rt_thread thread3;

// 线程堆栈
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
static rt_uint8_t thread3_stack[THREAD_STACK_SIZE];

// 线程入口函数
static void thread_entry1(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 1: I am the first thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

static void thread_entry2(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 2: I am the second thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

static void thread_entry3(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 3: I am the third thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

// 主函数
int main(void)
{
    // 初始化线程
    rt_thread_init(&thread1,
                   "thread1",
                   thread_entry1,
                   RT_NULL,
                   &thread1_stack[0],
                   sizeof(thread1_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);

    rt_thread_init(&thread2,
                   "thread2",
                   thread_entry2,
                   RT_NULL,
                   &thread2_stack[0],
                   sizeof(thread2_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);

    rt_thread_init(&thread3,
                   "thread3",
                   thread_entry3,
                   RT_NULL,
                   &thread3_stack[0],
                   sizeof(thread3_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);

    // 启动线程
    rt_thread_startup(&thread1);
    rt_thread_startup(&thread2);
    rt_thread_startup(&thread3);

    return 0;
}


逐行代码解释

#include <rtthread.h>

/*
|定义|
- 这三行定义了线程的栈大小、优先级和时间片。
- 栈大小是线程可以使用的内存量;
- 优先级决定了线程相对于其他线程的运行优先权;
- 时间片是线程在被强制切换之前可以运行的时间量。
*/
#define THREAD_STACK_SIZE 512
#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 5

/* 
|线程控制块|
- 定义了三个线程控制块
- 这些是RT-Thread用来管理线程的内部结构。
*/
static struct rt_thread thread1;
static struct rt_thread thread2;
static struct rt_thread thread3;

/*
|线程堆栈|
- 定义了三个线程的堆栈数组
- 并确保它们按RT-Thread要求的对齐方式对齐
- 这些堆栈用于存储线程的局部变量和调用历史。
*/
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
static rt_uint8_t thread3_stack[THREAD_STACK_SIZE];

/*
|线程入口函数|
- 定义了第一个线程的入口函数
- 这个函数无限循环,每次循环都打印一条消息然后延迟3秒。
*/
static void thread_entry1(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 1: I am the first thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

/*
|线程入口函数|
- 定义了第一二个线程的入口函数
- 这个函数无限循环,每次循环都打印一条消息然后延迟3秒。
*/
static void thread_entry2(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 2: I am the second thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

/*
|线程入口函数|
- 定义了第三个线程的入口函数
- 这个函数无限循环,每次循环都打印一条消息然后延迟3秒。
*/
static void thread_entry3(void *parameter)
{
    while (1)
    {
        rt_kprintf("Thread 3: I am the third thread.\n");
        rt_thread_mdelay(3000); // 3秒延时
    }
}

// 主函数
int main(void)
{
    /*
	|初始化线程|
	- 线程指针
	- 线程名称
	- 入口函数
	- 参数
	- 堆栈
	- 堆栈大小
	- 优先级 - 具体查询 RT-Thread 文档,不同芯片有不同等级划分
	- 时间片 - 具体查询 RT-Thread 文档
	*/
    rt_thread_init(&thread1,
                   "thread1",
                   thread_entry1,
                   RT_NULL,
                   &thread1_stack[0],
                   sizeof(thread1_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);
    /*
	|初始化线程|
	- 同理
	*/
    rt_thread_init(&thread2,
                   "thread2",
                   thread_entry2,
                   RT_NULL,
                   &thread2_stack[0],
                   sizeof(thread2_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);
    /*
	|初始化线程|
	- 同理
	*/    
	rt_thread_init(&thread3,
                   "thread3",
                   thread_entry3,
                   RT_NULL,
                   &thread3_stack[0],
                   sizeof(thread3_stack),
                   THREAD_PRIORITY,
                   THREAD_TIMESLICE);

    // 启动线程
    rt_thread_startup(&thread1);
    rt_thread_startup(&thread2);
    rt_thread_startup(&thread3);

    return 0;
}

在这里插入图片描述

  • 31
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
rtthread是一个开源的实时操作系统(RTOS),它旨在为嵌入式系统提供高效、可靠和易于使用的解决方案。rtthread内核小巧、灵活,并支持多种处理器架构。 MicroBlaze是一种基于Xilinx FPGA的32位处理器架构,它是一款软核处理器,可以通过FPGA的可编程逻辑实现,具有灵活性和可定制性。 rtthread microblaze就是将rtthread操作系统移植到MicroBlaze架构上的解决方案。通过将rtthread移植到MicroBlaze上,我们可以利用rtthread的实时性和可靠性来开发针对MicroBlaze的嵌入式系统。 rtthread microblaze的主要特点包括: 1. 小巧高效:rtthread内核经过精简设计,占用资源少,运行效率高。 2. 实时性能:rtthread具备实时操作系统的特性,能够满足对实时性要求较高的应用场景。 3. 多任务支持:rtthread microblaze支持多任务并行执行,在不同的任务之间可以进行任务切换,实现多线程的并发执行。 4. 丰富的组件库:rtthread提供了丰富的组件库,包括文件系统、网络协议栈、设备驱动等,可以大大简化开发过程。 5. 易于移植:rtthread microblaze具有良好的可移植性,可以方便地将rtthread移植到其他基于MicroBlaze的平台上。 总之,rtthread microblaze为基于MicroBlaze的嵌入式系统提供了一个可靠而高效的操作系统解决方案,使开发人员能够更加方便地开发出功能强大、实时性能高的嵌入式应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值