【STM32RT-Thread零基础入门】 6. 线程创建应用(线程挂起与恢复)

硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线

文章目录

  • 前言
  • 一、RT-Thread相关接口函数
    • 1. 挂起线程
    • 2. 恢复线程
  • 二、程序设计
    • 1. car_led.c
    • 2.car_led.h
    • 3. main.c
  • 三、程序测试
  • 总结


前言

在上一个任务中,通过停止命令把线程删除后,线程在系统中就不存在了,也无法再使线程重新运行。例如输入stop_led_thread命令后,led停止闪烁,但也无法重新开启LED灯闪烁功能。本任务通过修改停止命令的实现代码,同时增加恢复命令,使led灯闪烁功能可以暂停和恢复。


一、RT-Thread相关接口函数

1. 挂起线程

线程挂起是指把线程脱离就绪队列,使线程不参与调度器的调度。线程挂起使用下面的接口函数:

rt_err_t rt_thread_suspend (rt_thread_t thread);

线程挂起接口 rt_thread_suspend() 的参数和返回值见下表:

参数描述
thread线程句柄
返回RT_EOK: 线程挂起成功,-RT_ERROR: 线程挂起失败,因为该线程的状态并不是就绪状态

注:一个线程尝试挂起另一个线程是一个非常危险的行为,因此RT-Thread对此函数有严格的使用限制:该函数只能使用来挂起当前线程(即自己挂起自己),不可以在线程A中尝试挂起线程B。而且在挂起线程自己后,需要立刻调用 rt_schedule() 函数进行手动的线程上下文切换。用户只需要了解该接口的作用即可,不建议在程序中使用该接口。该接口可以视为是内部接口。这是因为A线程在尝试挂起B线程时,A线程并不清楚B线程正在运行什么程序,一旦B线程正在使用影响、阻塞其他线程(如C线程)的内核对象(例如互斥量、信号量等)时,如果此时其他线程也在等待这个内核对象,那么A线程尝试挂起B线程的操作将会引发其他线程(如C线程)的饥饿,严重危及系统的实时性。有些地方会将其描述为死锁,实际上这种现象不是死锁,但是也没有比死锁好到哪去。

当线程调用 rt_thread_delay() 时,线程将主动挂起;当调用 rt_sem_take(),rt_mb_recv() 等函数时,资源不可使用也将导致线程挂起。处于挂起状态的线程,如果其等待的资源超时(超过其设定的等待时间),那么该线程将不再等待这些资源,并返回到就绪状态;或者,当其他线程释放掉该线程所等待的资源时,该线程也会返回到就绪状态。

2. 恢复线程

恢复线程就是让挂起的线程重新进入就绪状态,并将线程放入系统的就绪队列中;如果被恢复线程在所有就绪态线程中,位于最高优先级链表的第一位,那么系统将进行线程上下文的切换。线程恢复使用下面的函数接口:

rt_err_t rt_thread_resume (rt_thread_t thread);

线程恢复接口 rt_thread_resume() 的参数和返回值见下表:

参数描述
thread线程句柄
返回RT_EOK: 线程恢复成功,-RT_ERROR: 线程恢复失败,因为该个线程的状态并不是 RT_THREAD_SUSPEND 状态

二、程序设计

在前一章节的基础上修改car_led.c、car_led.h和main.c三个文件即可,具体如下:

1. car_led.c

增加暂停标志、暂停设置接口,以及在线程中增加暂停执行代码

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"#define DBG_TAG "LED"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <stdlib.h>
#include "car_led.h"
/* 定义左右转向灯的控制引脚 */
#define LedLeft GET_PIN(D, 8)
#define LedRight GET_PIN(D, 9)
#define LedOn(pin) rt_pin_write(pin, PIN_LOW)
#define LedOff(pin) rt_pin_write(pin, PIN_HIGH)enum led_mode LedMod=LED_MODE_STOP;
void led_set_mode(enum led_mode m)
{LedMod = m;
}
/* 暂停运行标志变量,0表示运行,1表示暂停 */
static int stopFlag=0;
void led_thread_entry()
{rt_pin_mode(LedLeft, PIN_MODE_OUTPUT);rt_pin_mode(LedRight, PIN_MODE_OUTPUT);
while(1){/*判断是否暂停运行*/if(stopFlag){rt_thread_suspend(rt_thread_self());//挂起线程,只能自已挂起自已rt_schedule();//使用suspend挂起线程后,需手动进行线程上下文切换}switch(LedMod){case LED_MODE_STOP:LedOff(LedLeft);LedOff(LedRight);break;case LED_MODE_Double:LedOn(LedLeft);LedOn(LedRight);rt_thread_mdelay(500);LedOff(LedLeft);LedOff(LedRight);break;case LED_MODE_LEFT:LedOff(LedRight);LedOn(LedLeft);rt_thread_mdelay(250);LedOff(LedLeft);break;case LED_MODE_RIGHT:LedOff(LedLeft);LedOn(LedRight);rt_thread_mdelay(250);LedOff(LedRight);break;default:LOG_D("mode error\n");}rt_thread_mdelay(250);}
}
void ledmode(int argn, char *argv[])
{if(argn<2){LOG_W("ledmode #mode");return ;}led_set_mode(atoi(argv[1]));}
void led_stop_flag(int i)//设置暂停标志的接口
{stopFlag=i;
}/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(ledmode, set led flash mode);

2.car_led.h

代码如下:

#ifndef APPLICATIONS_CAR_LED_H_
#define APPLICATIONS_CAR_LED_H_/* 车灯闪烁模式定义 */
enum led_mode {LED_MODE_STOP=0, //停止闪烁LED_MODE_Double, //双闪LED_MODE_LEFT,   //左灯闪烁LED_MODE_RIGHT   //右灯闪烁
};
void led_thread_entry();               //线程入口函数声明
void led_set_mode(enum led_mode m);    //车灯闪烁模式设置声明
void led_stop_flag(int i); //接口声明,同时导出模块接口供其它模块使用#endif /* APPLICATIONS_CAR_LED_H_ */

3. main.c

主要修改stop_led_thread()函数的实现,同时增加线程恢复函数,并把线程恢复函数导出到msh命令中,使我们可以通过终端来恢复线程。

#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "car_led.h"    //包含LED控制模块头文件
#include "car_beep.h"   //包含蜂鸣器控制模块头文件#define THREAD_STACK_SIZE   1024   //定义线程栈大小
#define THREAD_PRIORITY     20     //定义线程优先级
#define THREAD_TIMESLICE    10     //定义线程时间片/* 栈首地址必须系统对齐 */
ALIGN(RT_ALIGN_SIZE)
static char beep_stack[THREAD_STACK_SIZE];  //定义栈空间
static struct rt_thread beepThread;    //静态方式定义beep线程控制块
rt_thread_t TidLed = RT_NULL;  //动态方式定义LED线程句柄int main(void)
{int ret;/* 动态方式创建线程 */TidLed = rt_thread_create("LED", led_thread_entry, RT_NULL,THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);if (TidLed != RT_NULL)//判断线程是否成功创建rt_thread_startup(TidLed);//成功则启动线程else {//否则打印日志并即出LOG_D("can not create LED thread!");return -1;}/* 采用静态方式初始化线程 */ret = rt_thread_init(&beepThread,"BEEP",beep_thread_entry,RT_NULL,&beep_stack[0],sizeof(beep_stack),THREAD_PRIORITY,THREAD_TIMESLICE);if (ret == RT_EOK) //判断线程是否成功创建rt_thread_startup(&beepThread); //成功则启动线程else { //否则打印日志并即出LOG_D("can not init beep thread!");return -1;}return RT_EOK;
}
void stop_led_thread()//暂停运行
{led_stop_flag(1);
}
void resume_led_thread()//恢复运行
{led_stop_flag(0);//先设置为运行rt_thread_resume(TidLed);//再恢复线程return;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(resume_led_thread, resume led thread);//唤醒命令
MSH_CMD_EXPORT(stop_led_thread, stop led thread);

三、程序测试

(1)系统启动后,使用命令“ledmode 1”使能车灯双闪,观察到车灯闪烁。
在这里插入图片描述
(2)输入命令“stop_led_thread”命令,观察到车灯停止闪烁,说明线程已经被挂起。
在这里插入图片描述
(3)输入命令“resume_led_thread”命令,观察到车灯重新闪烁,说明线程被重新唤醒。
在这里插入图片描述
(4)输入命令“ps”命令,如图所示,观察到BEEP和LED两个线程都处理挂起状态,这主要是因为ps命令输出时,CPU正在运行tshell程序(命令是在tshell线程上下文件中运行的),而此时BEEP和LED两个线程因为执行rt_thread_mdelay()函数而被挂起。
在这里插入图片描述


总结

本章节学习线程的挂起与恢复的应用

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

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

相关文章

Linux操作系统--常用指令(文件目录类指令)

(1).pwd指令 功能:显示当前工作目录的绝对路径。 如果你使用cd命令进行切换的时候不知道到了哪里,就可以使用该指令输出路径查看。 (2).cd命令 功能:用于切换路径 语法: cd + 路径(路径可以指绝对路径,也可以是相对路径)

URL中传递JSON字符串

今天遇见了一个需求&#xff0c;从post请求中在url里传递json字符串&#xff0c; 就是路径?参数11那种情况 最后怎么解决的呢&#xff1f; 需要使用前端方法&#xff0c;先用JSON.stringify格式化成字符串&#xff0c;再用encodeURIComponent把JSON里面的符号转转为url支持的…

ppt如何转pdf文档?用这个方法可将ppt转pdf

在现代社会中&#xff0c;PPT(幻灯片)已成为一种常见的演示工具&#xff0c;被广泛应用于学术、商务、培训等领域。然而&#xff0c;PPT文件的使用和分享存在一些问题&#xff0c;例如文件格式不兼容、内容修改易被篡改等。为了解决这些问题&#xff0c;将PPT转换为PDF格式已成…

AI夏令营第三期用户新增挑战赛学习笔记

1、数据可视化 1.数据探索和理解&#xff1a;数据可视化可以帮助我们更好地理解数据集的特征、分布和关系。通过可视化数据&#xff0c;我们可以发现数据中的模式、异常值、缺失值等信息&#xff0c;从而更好地了解数据的特点和结构。2.特征工程&#xff1a;数据可视化可以帮助…

TinyVue - 华为云 OpenTiny 出品的企业级前端 UI 组件库,免费开源,同时支持 Vue2 / Vue3,自带 TinyPro 中后台管理系统

华为最新发布的前端 UI 组件库&#xff0c;支持 PC 和移动端&#xff0c;自带了 admin 后台系统&#xff0c;完成度很高&#xff0c;web 项目开发又多一个选择。 关于 OpenTiny 和 TinyVue 在上个月结束的华为开发者大会2023上&#xff0c;官方正式进行发布了 OpenTiny&#…

成都睿趣科技:抖音开网店前期的流程是什么

随着互联网的快速发展&#xff0c;电子商务成为了商业领域中的一大利器&#xff0c;而在电商领域中&#xff0c;抖音作为一个强大的平台&#xff0c;也吸引了众多商家的目光。然而&#xff0c;要在抖音上开设一家成功的网店&#xff0c;并不是一件简单的事情&#xff0c;需要经…

研磨设计模式day12命令模式

目录 定义 几个参数 场景描述 代码示例 参数化设置 命令模式的优点 本质 何时选用 定义 几个参数 Command&#xff1a;定义命令的接口。 ConcreteCommand:命令接口的实现对象。但不是真正实现&#xff0c;是通过接收者的功能来完成命令要执行的操作 Receiver&#x…

无涯教程-进程 - 信号(Signals)

信号是对进程的通知&#xff0c;指示事件的发生。信号也称为软件中断&#xff0c;无法预知其发生&#xff0c;因此也称为异步事件。 可以用数字或名称指定信号&#xff0c;通常信号名称以SIG开头。可用信号kill –l(列出信号名称为l)检查可用信号&#xff0c;如下所示- 无论何…

骨传导耳机和普通耳机哪个危害大?一文读懂骨传导耳机!

作为一个5年重度运动爱好者&#xff0c;常年跑步、爬山、骑行&#xff0c;入手过的各类耳机超30款&#xff0c;用真实体验告诉大家&#xff0c;骨传导耳机和普通耳机哪个危害大&#xff01; 首先大家要知道的是&#xff0c;不管什么类型的耳机&#xff0c;如说说音量过大&…

SpringBoot生成和解析二维码完整工具类分享(提供Gitee源码)

前言&#xff1a;在日常的开发工作当中可能需要实现一个二维码小功能&#xff0c;我参考了网上很多关于SpringBoot生成二维码的教程&#xff0c;最终还是自己封装了一套完整生成二维码的工具类&#xff0c;可以支持基础的黑白二维码、带颜色的二维码、带Logo的二维码、带颜色和…

Spring Cloud Alibaba-Sentinel-Sentinel入门

1 什么是Sentinel Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。Sentinel 具有以下特征: 丰富的应用场景&#xff1a;Sentinel 承接了阿里…

【深度学习】实验02 鸢尾花数据集分析

文章目录 鸢尾花数据集分析决策树K-means 鸢尾花数据集分析 决策树 # 导入机器学习相关库 from sklearn import datasets from sklearn import treeimport matplotlib.pyplot as plt import numpy as np# Iris数据集是常用的分类实验数据集&#xff0c; # 由Fisher, 1936收集…

JetBrains 2023.2全新发布!IDEA、PyCharm等支持AI辅助

日前JetBrains官方正式宣布旗下IDE系列今年第二个重要版本——v2023.2全新发布&#xff0c;涵盖了 IntelliJ IDEA、PyCharm、WebStorm等一众知名产品&#xff0c;接下来我们一起详细了解一下他们的更新重点吧~ IntelliJ IDEA v2023.2——引入AI辅助开发 IntelliJ IDEA 2023.2…

动捕设备助力打造沉浸式虚拟现实体验

在纪录片《超时空寻找》中&#xff0c;借助了实时动捕设备&#xff0c;基于三维数字人技术进行老战士与历史场景还原&#xff0c;让抗美援朝老战士可以通过虚拟现实技术&#xff0c;跨越时空与战友实现隔空对话。 随着动捕设备的不断发展&#xff0c;虚拟现实技术越来越成熟&a…

WGS84地球坐标系,GCJ02火星坐标系,BD09百度坐标系简介与转换 资料收集

野火 ATGM332D简介 高性能、低功耗 GPS、北斗双模定位模块 STM32 GPS定位_为了维护世界和平_的博客-CSDN博客 秉火多功能调试助手上位机开源&#xff01;共六款软件&#xff0c;学到你吐... , - 电脑上位机 - 野火电子论坛 - Powered by Discuz! https://www.firebbs.cn/for…

M1 Pro 利用docker 搭建pytho2的开发环境,以vscode连接开发为例

使用 M1 Pro &#xff08;不支持python2的安装&#xff09;开发&#xff0c;需要使用 Python 2.7 的环境&#xff0c;在使用 pyenv 安装 Python 2 时遇到了各种奇怪的问题。最终&#xff0c;我决定使用 Docker 搭建开发环境&#xff0c;并使用 VS Code 连接到本地容器。以下是详…

Unity 应用消息中心-MessageCenter

Ps&#xff1a;主要解决耦合问题&#xff0c;把脚本之间的联系通过不同消息类型事件形式进行贯通 1.MessageCenter主脚本 2.DelegateEvent消息类型脚本 3.MC_Default_Data具体接收类脚本 using System; using System.Collections; using System.Collections.Generic; using …

unity 模型显示在UI上 并交互(点击、旋转、缩放)

项目工程&#xff1a;unity模型显示在UI上并交互&#xff08;点击、旋转、缩放&#xff09;资源-CSDN文库 1.在Assets创建 Render Texture&#xff08;下面会用到&#xff09;&#xff0c;根据需要设置Size 2.创建UIRawImage&#xff0c;并把Render Texture赋上 3.创建相机&am…

Docker安装并配置Pushgateway

Linux下安装Docker请参考&#xff1a;Linux安装Docker 简介 Pushgateway是Prometheus的一个组件&#xff0c;prometheus server默认是通过Exporter主动获取数据&#xff08;默认采取pull拉取数据&#xff09;&#xff0c;Pushgateway则是通过exporter主动方式推送数据到Pushg…

前端需要理解的CSS知识

CSS&#xff08;层叠样式表&#xff0c;Cascading Style Sheets&#xff09;不是编程语言&#xff0c;而是用来描述 HTML 或 XML&#xff08;包括如 SVG、MathML 或 XHTML 之类的 XML 分支语言&#xff09;文档的表现与展示效果的样式表语言。CSS3是CSS的最新标准&#xff0c;是…