RT-Thread: 线程创建及应用

说明:这里记录 RT-Thread 的具体创建过程,相当于线程创建的一个模式,具体线程相关的信息没做介绍, RT-Thread 的官方文档里面已经有详细介绍,如有需要请移步官网。

官网链接:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/thread/thread

1. 线程相关函数:

//创建动态线程
//一个线程要成为可执行的对象,就必须由操作系统的内核来为它创建一个线程。可以通过如下的接口创建一个动态线程:
//调用这个函数时,系统会从动态堆内存中分配一个线程句柄以及按照参数中指定的栈大小从动态堆内存中分配相应的空间。
//分配出来的栈空间是按照 rtconfig.h 中配置的 RT_ALIGN_SIZE 方式对齐。线程创建 rt_thread_create() 
//的参数和返回值见下表:	
rt_thread_t rt_thread_create(const char* name,void (*entry)(void* parameter),void* parameter,rt_uint32_t stack_size,rt_uint8_t priority,rt_uint32_t tick);//删除线程				
//对于一些使用 rt_thread_create() 创建出来的线程,当不需要使用,或者运行出错时,
//我们可以使用下面的函数接口来从系统中把线程完全删除掉:
rt_err_t rt_thread_delete(rt_thread_t thread);//初始化静态线程
//线程的初始化可以使用下面的函数接口完成,来初始化静态线程对象:
rt_err_t rt_thread_init(struct rt_thread* thread,const char* name,void (*entry)(void* parameter), void* parameter,void* stack_start, rt_uint32_t stack_size,rt_uint8_t priority, rt_uint32_t tick);//删除静态线程
//对于用 rt_thread_init() 初始化的线程,使用 rt_thread_detach() 
//将使线程对象在线程队列和内核对象管理器中被脱离。线程脱离函数如下:
rt_err_t rt_thread_detach (rt_thread_t thread);//启动线程
//创建(初始化)的线程状态处于初始状态,并未进入就绪线程的调度队列,
//我们可以在线程初始化 / 创建成功后调用下面的函数接口让该线程进入就绪态:
rt_err_t rt_thread_startup(rt_thread_t thread);//获得当前线程
//在程序的运行过程中,相同的一段代码可能会被多个线程执行,
//在执行的时候可以通过下面的函数接口获得当前执行的线程句柄:
rt_thread_t rt_thread_self(void);//使线程让出处理器资源
//当前线程的时间片用完或者该线程主动要求让出处理器资源时,它将不再占有处理器,
//调度器会选择相同优先级的下一个线程执行。线程调用这个接口后,这个线程仍然在就绪队列中。
//线程让出处理器使用下面的函数接口:rt_err_t rt_thread_yield(void);//使线程睡眠
//在实际应用中,我们有时需要让运行的当前线程延迟一段时间,在指定的时间到达后重新运行,
//这就叫做 “线程睡眠”。线程睡眠可使用以下三个函数接口:
//这三个函数接口的作用相同,调用它们可以使当前线程挂起一段指定的时间,当这个时间过后,
//线程会被唤醒并再次进入就绪状态。这个函数接受一个参数,该参数指定了线程的休眠时间。
//线程睡眠接口 rt_thread_sleep/delay/mdelay() 的参数和返回值见下表:
rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);//挂起和恢复线程
//当线程调用 rt_thread_delay() 时,线程将主动挂起;当调用 rt_sem_take(),rt_mb_recv() 
//等函数时,资源不可使用也将导致线程挂起。处于挂起状态的线程,如果其等待的资源超时(超过其设定的等待时间),
//那么该线程将不再等待这些资源,并返回到就绪状态;或者,当其他线程释放掉该线程所等待的资源时,该线程也会返回到就绪状态。
rt_err_t rt_thread_suspend (rt_thread_t thread);//恢复挂起线程
//恢复线程就是让挂起的线程重新进入就绪状态,并将线程放入系统的就绪队列中;如果被恢复线程在所有就绪态线程中,
//位于最高优先级链表的第一位,那么系统将进行线程上下文的切换。线程恢复使用下面的函数接口:
rt_err_t rt_thread_resume (rt_thread_t thread);//控制线程
//当需要对线程进行一些其他控制时,例如动态更改线程的优先级,可以调用如下函数接口:
rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);//设置和删除空闲钩子
//空闲钩子函数是空闲线程的钩子函数,如果设置了空闲钩子函数,就可以在系统执行空闲线程时,
//自动执行空闲钩子函数来做一些其他事情,比如系统指示灯。设置 / 删除空闲钩子的接口如下:
rt_err_t rt_thread_idle_sethook(void (*hook)(void));//设置空闲钩子函数
rt_err_t rt_thread_idle_delhook(void (*hook)(void));//删除空闲钩子函数//设置调度器钩子
//在整个系统的运行时,系统都处于线程运行、中断触发 - 响应中断、切换到其他线程,甚至是线程间的切换过程中,
//或者说系统的上下文切换是系统中最普遍的事件。有时用户可能会想知道在一个时刻发生了什么样的线程切换,
//可以通过调用下面的函数接口设置一个相应的钩子函数。在系统线程切换时,这个钩子函数将被调用:
//注:请仔细编写你的钩子函数,稍有不慎将很可能导致整个系统运行不正常(在这个钩子函数中,基本上不允许调用系统
//API,更不应该导致当前运行的上下文挂起)。
void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to));

2. 示例1,提取实际项目有关线程创建和线程入口函数部分代码,以作备忘。

/* 线程入口函数     打印输出 ADC 处理完一轮的数据 */
static void adc_buffer_printf_entry(void *param)
{while(1){/* 一直等,直到获取到信号量 */rt_sem_take(&rx_sem_adc_dma, RT_WAITING_FOREVER); /*  等待时间:一直等 */for (uint8_t var = 0; var < 60; ++var){rt_kprintf("VH12 CH = %d, DATA = %d \r\n", var,adc_data.adc_all_VH12[var]);}for (uint8_t var = 0; var < 10; ++var){rt_kprintf("NTC CH = %d, DATA = %d \r\n", var,adc_data.adc_all_NTC[var]);}rt_kprintf("VIN_V =  %d \r\n",adc_data.adc_all_V_I[0]);rt_kprintf("VIN_I =  %d \r\n",adc_data.adc_all_V_I[1]);rt_kprintf("VHT_V =  %d \r\n",adc_data.adc_all_V_I[2]);rt_kprintf("VHT_V =  %d \r\n",adc_data.adc_all_V_I[3]);rt_thread_yield();/* 放弃剩余时间片,进行一次线程切换 */}
}/* 创建线程 函数 */
void adc_buffer_printf(void)
{rt_thread_t tid1;//创建线程控制块指针来接收线程创建函数的返回值,目的是通过返回值判断线程是否创建ok/* 创建线程 */tid1 = rt_thread_create("adc_buffer_printf",     //线程名称,系统打印线程时会显示这个线程的名字adc_buffer_printf_entry, //线程入口函数,入口函数函数名RT_NULL,                 //入口参数300,                     //线程栈大小,单位是字节10,                      //设置优先级100);                    //时间片参数,时间片是在有多个相同优先级线程时,这个线程每次被执行多少个时间片/* 如果获得线程控制块,启动这个线程 */if (tid1 != RT_NULL)rt_thread_startup(tid1); //启动线程else{rt_kprintf("Failed to create < adc_buffer_printf > \r\n"); //创建失败,打印输出,创建失败的具体 线程名return;}}

3. 线程应用示例 2

下面给出在 Keil 模拟器环境下的应用示例。

/* 线程示例 */

#include <rtthread.h>#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5static rt_thread_t tid1 = RT_NULL;/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter)
{rt_uint32_t count = 0;while (1){/* 线程 1 采用低优先级运行,一直打印计数值 */rt_kprintf("thread1 count: %d\n", count ++);rt_thread_mdelay(500);}
}ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
/* 线程 2 入口 */
static void thread2_entry(void *param)
{rt_uint32_t count = 0;/* 线程 2 拥有较高的优先级,以抢占线程 1 而获得执行 */for (count = 0; count < 10 ; count++){/* 线程 2 打印计数值 */rt_kprintf("thread2 count: %d\n", count);}rt_kprintf("thread2 exit\n");/* 线程 2 运行结束后也将自动被系统脱离 */
}/* 线程示例 */
int thread_sample(void)
{/* 创建线程 1,名称是 thread1,入口是 thread1_entry*/tid1 = rt_thread_create("thread1",thread1_entry, RT_NULL,THREAD_STACK_SIZE,THREAD_PRIORITY, THREAD_TIMESLICE);/* 如果获得线程控制块,启动这个线程 */if (tid1 != RT_NULL)rt_thread_startup(tid1);/* 初始化线程 2,名称是 thread2,入口是 thread2_entry */rt_thread_init(&thread2,"thread2",thread2_entry,RT_NULL,&thread2_stack[0],sizeof(thread2_stack),THREAD_PRIORITY - 1, THREAD_TIMESLICE);rt_thread_startup(&thread2);return 0;
}/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_sample, thread sample);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【揭秘APT攻击】——内网渗透实战攻略,带你领略网络安全的绝密世界!

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 介绍 什么是内网&#xff1f; 什么是内网渗透&#xff1f; 内网渗透的目的&#xff1a; 内网…

天鹅目标检测数据集VOC格式280张

天鹅&#xff0c;一种优雅而美丽的鸟类&#xff0c;以其洁白的羽毛、优美的身姿和动人的歌声而闻名。 天鹅属于鸟纲、鸭科&#xff0c;是一种大型水禽。它们的羽毛通常是白色、黑色或灰色&#xff0c;非常光滑且富有光泽。天鹅的头部和颈部非常细长&#xff0c;呈现出优雅的曲…

面试题-手撕NMS(非极大值抑制)

非极大值抑制&#xff08;Non-Maximum Suppression&#xff0c;NMS&#xff09;是一种常用于目标检测和计算机视觉中的算法&#xff0c;用于去除重叠的边界框&#xff0c;保留最可能是真实目标的边界框。 其核心就是对一组检测框&#xff0c;找出其中属于同一个类别且分数最高…

烟雾识别摄像机

烟雾识别摄像机是一种具有智能识别功能的监控设备&#xff0c;它能够通过图像识别技术检测和识别烟雾&#xff0c;提供实时监测和报警功能。这种摄像机通常应用于各种场所&#xff0c;如工厂、仓库、办公楼、酒店等&#xff0c;起到了重要的安全监测作用。 烟雾识别摄像机的工作…

C++入门【26-C++ Null 指针】

在变量声明的时候&#xff0c;如果没有确切的地址可以赋值&#xff0c;为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。 NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序&#xff1a; 实例 #include <iostream> using…

新手练习项目 4:简易2048游戏的实现(C++)

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#xff09; 目录 一、效果图二、代码&#xff08;带注释&#xff09;三、说明 一、效果图 二、代码&#xff08;带…

光伏方案设计有什么注意点?

光伏方案设计是实现光伏发电系统高效运行的关键环节。在进行光伏方案设计时&#xff0c;有几个重要的注意点需要特别关注。 首先&#xff0c;要充分考虑地理位置和气候条件。不同地区的日照时数、太阳辐射强度和日照角度都有所不同&#xff0c;这些因素直接影响光伏发电系统的发…

FS【1】:SSP

文章目录 前言1. Abstract2. Introduction2.1. Motivation2.1.1. Few-shot Segmentation (FSS) Task2.1.2. Few-shot Segmentation (FSS) Problem 2.2. Contribution 3. Methods3.1. Motivation3.2. Overview of the architecture4.3. Self-support Prototype4.4. Adaptive Sel…

C++:多态究竟是什么?为何能成为面向对象的重要手段之一?

C&#xff1a;多态究竟是什么&#xff1f;为何能成为面向对象的重要手段之一&#xff1f; 前言一、多态的概念二、多态的定义及实现2.1 多态的构成条件2. 2 虚函数2.3 虚函数的重写2.3.1 虚函数重写的例外1&#xff1a;协变(基类与派生类虚函数返回值类型不同)2.3.2 虚函数重写…

领域驱动模型之各层实体严格分层处理

为什么要分层处理呢&#xff1f; 在领域驱动模型中&#xff0c;分为应用层&#xff08;application&#xff09;、领域层&#xff08;domain&#xff09;、基础设施层&#xff08;infrastructure&#xff09;。各层只能处理和访问自己所属层的 entity 或者 dto 对象&#xff0…

基于ssm的理财通的设计与实现+jsp论文

摘 要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对理财信息管理的提升&#xff0c…

针对大规模服务日志敏感信息的长效治理实践

文章目录 1 背景2 目标与措施3 实施3.1 脱敏工具类3.2 JSON脱敏3.3 APT自动脱敏3.3.1 本地缓存问题3.3.2 JDK序列化问题 3.4 弃用方案 4 规划5 总结 1 背景 近年来&#xff0c;国家采取了多项重要举措来加强个人数据保护&#xff0c;包括实施《中华人民共和国网络安全法》和《…

TypeError: Cannot read properties of undefined (reading ‘namespace‘)

项目场景&#xff1a; 背景&#xff1a; Java 项目中使用 activi 流程引擎&#xff0c; 创建一个带有排他网关的 申请审核流程&#xff0c; 创建之后 查看 流程图出现 如下所示的 错误信息。 前端页面 不显示 任何 流程图信息。 问题描述 问题&#xff1a; 例如&#xff1…

鸿蒙系列--属性动画

一、定义 当组件的通用属性发生改变时而产生的属性渐变效果 说明&#xff1a; 当组件的通用属性发生改变时&#xff0c;组件状态由初始状态逐渐变为结束状态的过程中&#xff0c;会创建多个连续的中间状态&#xff0c;逐帧播放后&#xff0c;就会形成动画 二、创建 给组件(如…

SCS模型(径流曲线法)概述

目录 1.介绍&#xff1a;2.计算公式&#xff1a;参考文献&#xff1a;小结&#xff1a; 1.介绍&#xff1a; SCS模型&#xff08;径流曲线法&#xff09;是由美国农业部水土保持局(Soil Conservation Service) 基于经验提出&#xff0c;最初用于预测在农业用地小型流域降雨所累…

【算法每日一练]-dfs (保姆级教程 篇9) #俄罗斯方块 #ABC Puzzle #lnc的工资

目录 今日知识点&#xff1a; 二维图形的状态压缩&#xff0c;存下所有的合法状态然后暴力遍历 dfs的优化剪枝 二项式定理 俄罗斯方块 ABC Puzzle lnc的工资 俄罗斯方块 322D 题意&#xff1a;在4*4方格中分别给出3个俄罗斯方块&#xff0c;问是否可以经过旋转&#xf…

C/C++动态内存管理

文章目录 前言1.C/C内存分布2.C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3.C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. operator new与operator delete函数4.1 operator new与operator delete函数 5. new和delete的实现原…

软件测试|MySQL BETWEEN AND:范围查询详解

简介 在MySQL数据库中&#xff0c;使用BETWEEN AND操作符可以进行范围查询&#xff0c;即根据某个字段的值在指定范围内进行检索数据。这个操作符非常有用&#xff0c;因为它可以让我们轻松地筛选出位于两个特定值之间的数据&#xff0c;而不需要使用复杂的条件语句。 BETWEE…

数据挖掘在制造业中的预测与优化应用

随着大数据时代的到来&#xff0c;数据挖掘技术在各行各业的应用日益广泛&#xff0c;尤其在制造业中&#xff0c;其对于提升生产效率、降低运营成本、优化供应链管理等方面发挥着不可替代的作用。本文将探讨数据挖掘在制造业中的预测与优化应用&#xff0c;通过深入剖析实际案…

qtcreator一次性加载多个项目

目录 1. 问题的提出 2. 解决方法 3. 注意的问题 1. 问题的提出 有时一个软件系统由一个主程序&#xff0c;很多so或dll工程构成&#xff0c;每次打开qtcreator一个一个pro工程往qtcreator加&#xff0c;当项目很多时&#xff0c;很费时间、很麻烦&#xff0c;虽然qt…