【STM32RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)

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

文章目录

  • 前言
  • 一、线程管理接口介绍
  • 二、任务:使用多线程的方式同时实现led闪烁和按键控制喇叭(扫描法)
    • 1. RT-Thread相关接口函数
      • (1)创建和删除线程
      • (2)初始化和脱离线程
      • (3)启动线程
      • (4)线程睡眠
    • 2. 代码实现
      • (1)led灯闪烁功能模块实现
      • (2)按键控制喇叭功能模块实现
      • (3)main()程序设计
    • 3. 程序测试
  • 总结


前言

本章主要讲线程的工作机制和管理方法,通过实例讲解如何使用多线程完成多任务开发。


一、线程管理接口介绍

RT-Thread用线程控制块来描述和管理一个线程,一个线程对应一个线程控制块。线程控制块由结构体struct rt_thread表示,它用于存放线程的所有一些信息,例如优先级、线程名称、线程状态等,也包含线程与线程之间连接用的链表结构,线程等待事件集合等,详细定义如下:

/* 线程控制块 */
struct rt_thread
{/* rt 对象 */char        name[RT_NAME_MAX];     /* 线程名称 */rt_uint8_t  type;                   /* 对象类型 */rt_uint8_t  flags;                  /* 标志位 */rt_list_t   list;                   /* 对象列表 */rt_list_t   tlist;                  /* 线程列表 *//* 栈指针与入口指针 */void       *sp;                      /* 栈指针 */void       *entry;                   /* 入口函数指针 */void       *parameter;              /* 参数 */void       *stack_addr;             /* 栈地址指针 */rt_uint32_t stack_size;            /* 栈大小 *//* 错误代码 */rt_err_t    error;                  /* 线程错误代码 */rt_uint8_t  stat;                   /* 线程状态 *//* 优先级 */rt_uint8_t  current_priority;    /* 当前优先级 */rt_uint8_t  init_priority;        /* 初始优先级 */rt_uint32_t number_mask;......rt_ubase_t  init_tick;               /* 线程初始化计数值 */rt_ubase_t  remaining_tick;         /* 线程剩余计数值 */struct rt_timer thread_timer;      /* 内置线程定时器 */void (*cleanup)(struct rt_thread *tid);  /* 线程退出清除函数 */rt_uint32_t user_data;                      /* 用户数据 */
};
  • init_priority 是线程创建时指定的线程优先级,在线程运行过程当中是不会被改变的(除非用户执行线程控制函数进行手动调整线程优先级)。
  • cleanup 会在线程退出时,被空闲线程回调一次以执行用户设置的清理现场等工作。
  • user_data 可由用户挂接一些数据信息到线程控制块中,以提供一种类似线程私有数据的实现方式。

线程的创建、启动、删除等操作,都与线程控制块相关,RT-Thread提供线程管理和控制的一些函数,具体如下:

  • rt_thread_create() 创建线程
  • rt_thread_delete() 删除线程
  • rt_thread_init() 初始化线程
  • rt_thread_detach() 脱离线程
  • rt_thread_startup() 启动线程
  • rt_thread_self() 活得当前正在运行的线程,返回值位rt_thread_t类型(线程的句柄)
  • rt_thread_yield() 使线程让出处理器资源
  • rt_thread_sleep() 使线程睡眠指定tick,调用该函数,线程会被挂起
  • rt_thread_delay() 使线程延迟指定tick,调用该函数,线程会被挂起
  • rt_thread_mdelay() 使线程睡眠指定毫秒,调用该函数,线程会被挂起
  • rt_thread_suspend() 挂起线程
  • rt_thread_resume() 恢复线程
  • rt_thread_control() 控制线程

二、任务:使用多线程的方式同时实现led闪烁和按键控制喇叭(扫描法)

任务描述:在main线程中实现LED灯闪烁的功能,同时创建一个线程单独实现按键控制喇叭的功能,按键的识别使用扫描法。另外,要求可以通过命令控制灯的闪烁模式。硬件电路如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. RT-Thread相关接口函数

(1)创建和删除线程

一个线程要成为可执行的对象,就必须由操作系统的内核来为它创建一个线程。线程可以动态创建和删除。

① 创建线程

可以通过如下的接口创建一个动态线程:

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);

调用这个函数时,系统会从动态堆内存中分配一个线程句柄以及按照参数中指定的栈大小从动态堆内存中分配相应的空间。分配出来的栈空间是按照 rtconfig.h 中配置的 RT_ALIGN_SIZE 方式对齐。

线程创建rt_thread_create() 的参数和返回值见下表:

参数描述
name线程的名称;线程名称的最大长度由 rtconfig.h 中的宏 RT_NAME_MAX 指定,多余部分会被自动截掉
entry线程入口函数
parameter线程入口函数参数
stack_size线程栈大小,单位是字节
priority线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0~255,数值越小优先级越高,0 代表最高优先级
tick线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回Thread:线程创建成功,返回线程句柄;RT_NULL:线程创建失败

② 删除线程

对于一些使用 rt_thread_create() 创建出来的线程,当不需要使用,或者运行出错时,我们可以使用下面的函数接口来从系统中把线程完全删除掉:

rt_err_t rt_thread_delete(rt_thread_t thread);

调用该函数后,线程对象将会被移出线程队列并且从内核对象管理器中删除,线程占用的堆栈空间也会被释放,收回的空间将重新用于其他的内存分配。
实际上,用 rt_thread_delete() 函数删除线程接口,仅仅是把相应的线程状态更改为 RT_THREAD_CLOSE 状态,然后放入到 rt_thread_defunct 队列中;
而真正的删除动作(释放线程控制块和释放线程栈)需要到下一次执行空闲线程时,由空闲线程完成最后的线程删除动作。
线程删除 rt_thread_delete() 接口的参数和返回值见下表:

参数描述
thread要删除的线程句柄
返回RT_EOK 删除线程成功,-RT_ERROR 删除线程失败

注:rt_thread_create() 和 rt_thread_delete() 函数仅在使能了系统动态堆时才有效(即 RT_USING_HEAP 宏定义已经定义了)。

(2)初始化和脱离线程

静态方法使用线程

① 初始化线程

线程的初始化可以使用下面的函数接口完成,来初始化静态线程对象:

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);

静态线程的线程句柄(或者说线程控制块指针)、线程栈由用户提供。

静态线程是指线程控制块、线程运行栈一般都设置为全局变量,在编译时就被确定、被分配处理,内核不负责动态分配内存空间。

需要注意的是,用户提供的栈首地址需做系统对齐(例如 ARM 上需要做 4 字节对齐)。线程初始化接口 rt_thread_init() 的参数和返回值见下表:

参数描述
thread线程句柄。线程句柄由用户提供出来,并指向对应的线程控制块内存地址
name线程的名称;线程名称的最大长度由 rtconfig.h 中定义的 RT_NAME_MAX 宏指定,多余部分会被自动截掉
entry线程入口函数
parameter线程入口函数参数
stack_start线程栈起始地址
stack_size线程栈大小,单位是字节。在大多数系统中需要做栈空间地址对齐(例如 ARM 体系结构中需要向 4 字节地址对齐)
priority线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0 ~ 255,数值越小优先级越高,0 代表最高优先级
tick线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回RT_EOK 线程创建成功,-RT_ERROR 线程创建失败

② 脱离线程

对于用 rt_thread_init() 初始化的线程,使用 rt_thread_detach() 将使线程对象在线程队列和内核对象管理器中被脱离。线程脱离函数如下:

rt_err_t rt_thread_detach (rt_thread_t thread);

线程脱离接口 rt_thread_detach() 的参数和返回值见下表:

参数描述
thread线程句柄,它应该是由rt_thread_init进行初始化的线程句柄
返回RT_EOK: 线程脱离成功,-RT_ERROR: 线程脱离失败

**这个接口函数与 rt_thread_delete() 函数相对应, rt_thread_delete() 函数操作的对象是 rt_thread_create()创建的句柄,而 rt_thread_detach()函数操作的对象是 rt_thread_init()初始化的线程控制块。**同样线程本身不应调用这个接口脱离线程本身。

(3)启动线程

创建(初始化)的线程状态处于初始状态,并未进入就绪线程的调度队列,我们可以在线程初始化 / 创建成功后调用下面的函数接口让该线程进入就绪态:

rt_err_t rt_thread_startup(rt_thread_t thread);

当调用这个函数时,将把线程的状态更改为就绪状态,并放到相应优先级队列中等待调度。如果新启动的线程优先级比当前线程优先级高,将立刻切换到这个线程。线程启动接口 rt_thread_startup() 的参数和返回值见下表:

参数描述
thread线程句柄
返回RT_EOK:线程启动成功,-RT_ERROR 线程启动失败

(4)线程睡眠

在实际应用中,我们有时需要让运行的当前线程延迟一段时间,在指定的时间到达后重新运行,这就叫做 “线程睡眠”。线程睡眠可使用以下三个函数接口:

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_sleep/delay/mdelay() 的参数和返回值见下表:

参数描述
tick/ms线程睡眠的时间:sleep/delay 的传入参数 tick 以 1 个 OS Tick 为单位 ;mdelay 的传入参数 ms 以 1ms 为单位;
返回RT_EOK: 操作成功

2. 代码实现

本任务主要实现两个功能:灯闪烁、按键控制喇叭。这个两个功能都可以采用循环结构来设计,但是在第3章的任务中发现,单线程中采用循环结构同时实现这两个功能,在代码实现上比较困难,所以本任务分两个线程来实现:一个线程实现灯闪烁,另一个线程实现按键扫描并控制喇叭开关。
构建两个小功能模块,分别是灯闪烁和按键控制喇叭。

(1)led灯闪烁功能模块实现

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);    //车灯闪烁模式设置声明#endif /* APPLICATIONS_CAR_LED_H_ */

car_led.c是具体的函数实现,本文件除了实现闪灯线程的入口函数以外,还按任务要求,实现闪灯模式设置接口,并把设置接口导出到msh命令列表中,导出后,用户就可以通过在终端输入命令来改变闪烁的模式,代码如下:

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"#define DBG_TAG "LED"    //定义日志打印标签
#define DBG_LVL DBG_LOG  //定义日志打印级别
/* 包含日志打印头文件。注意,以上2个宏定义一定要在这个头文件前定义才有效*/
#include <rtdbg.h> 
#include <stdlib.h>      //atoi()函数需要包含的头文件
#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;
}/* 车灯控制线程入口函数定义 */
void led_thread_entry()
{/*设置车灯控制引脚模式为输出模式*/rt_pin_mode(LedLeft, PIN_MODE_OUTPUT);rt_pin_mode(LedRight, PIN_MODE_OUTPUT);while(1){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);//此处延时主要是为了让出CPU,不能让线程一直占用CPU}
}
/*msh命令接口*/
void ledmode(int argn, char *argv[])
{if(argn<2){LOG_W("ledmode #mode");return ;}led_set_mode(atoi(argv[1]));//通过atoi函数把字符变量转为整型变量
}
/* 导出到 msh 命令列表中,MSH_CMD_EXPORT(command,desc),其中command为函数名字,desc为用于描述命令用法或功能的字符串,可以自定 */
MSH_CMD_EXPORT(ledmode, set led flash mode);

(2)按键控制喇叭功能模块实现

扫描法进行按键扫描。
car_beep.h代码如下:

#ifndef APPLICATIONS_CAR_BEEP_H_
#define APPLICATIONS_CAR_BEEP_H_
void beep_thread_entry();//按键扫描并控制蜂鸣器的接口声明
#endif /* APPLICATIONS_CAR_BEEP_H_ */

car_beep.c

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
#define DBG_TAG "BEEP"     //定义日志打印标签
#define DBG_LVL DBG_LOG    //定义日志打印级别
#include <rtdbg.h>         //以上2个宏定义一定要在这个头文件前定义才有效
#define KeyBeep GET_PIN(A, 0)  //按键引脚定义
#define Beep GET_PIN(A, 5)     //蜂鸣器引脚定义
/*按键扫描并控制蜂鸣器的接口实现*/
int beep_thread_entry(void)
{/* 把蜂鸣器引脚设置为推拉模式 */rt_pin_mode(Beep, PIN_MODE_OUTPUT);/* 把按键引脚设置为上拉输入模式 */rt_pin_mode(KeyBeep, PIN_MODE_INPUT_PULLUP);while (1){if(PIN_LOW==rt_pin_read(KeyBeep)){//按键按下rt_thread_mdelay(20);//延时去抖if(PIN_LOW==rt_pin_read(KeyBeep))rt_pin_write(Beep, PIN_LOW);//蜂鸣器响}elsert_pin_write(Beep, PIN_HIGH);//否则,蜂鸣器不响rt_thread_mdelay(100);//每0.1秒进行一次按键扫描,线程要有让出CPU的时候}return RT_EOK;
}

注:本任务,两个线程都采用了无线循环模式,为了不让线程陷入死循环操作,两个线程都在每次循环后通过调用延时函数来让出CPU使用权。但这种让出方式还不是最好的方式,通常可以通过让线程灯带信号量的方式使线程挂起,从而达到在线程空闲时让出CPU的效果,具体参考后面线程同步相关章节。

(3)main()程序设计

main()程序主要实现线程的创建,在本任务中,我们分别采用动态方法和静态方法来创建线程,主要是方便了解两种方法的使用,具体代码如下:

#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(void)//删除led线程命令
{rt_thread_delete(TidLed);//动态创建的线程用delete删除
}
void stop_beep_thread(void) //删除beep线程命令
{rt_thread_detach(&beepThread);//静态初始化的线程用detach删除
}/* 导出到 msh 命令列表中*/
MSH_CMD_EXPORT(stop_led_thread, delete led thread);
MSH_CMD_EXPORT(stop_beep_thread, delete beep thread);

复制以上代码文件到applicastions目录中,构建并下载程序到开发板。

3. 程序测试

(1)系统启动后,两个LED等常亮无闪烁,终端输入ps命令查看系统线程情况,发现系统中新增了2个线程,分别使BEEP和LED,如图所示
在这里插入图片描述
(2)在终端中输入help命令查看系统命令支持情况,发现系统新增了程序中导出的3个命令ledmode、stop_led_thread、stop_beep_thread,如下图所示:
在这里插入图片描述
(3)终端输入ledmode 1、ledmode 2、ledmode 3等命令后,观察到车灯闪烁分别变为“双闪”“左灯闪”“右灯闪”。
在这里插入图片描述
(4)按下按键后,喇叭发出响声。
(5)松开按键后,喇叭停止发声。
(6)一直按住按键不松开,喇叭发出响声的同时,车灯继续闪烁。
(7)通过终端输入停止车灯闪烁命令stop_led_thread,观察车灯不再闪烁;通过ps命令查看系统线程情况,发现系统中不存在LED线程了

在这里插入图片描述

(8)通过终端输入停止喇叭响声命令stop_beep_thread,按下按键时喇叭不响;通过ps命令查看系统线程情况,发现系统中不存在BEEP线程了

在这里插入图片描述


总结

本文讲了线程创建的应用

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

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

相关文章

STM32 FLASH 读写数据

1. 《STM32 中文参考手册》&#xff0c;需要查看芯片数据手册&#xff0c;代码起始地址一般都是0x8000 0000&#xff0c;这是存放整个项目代码的起始地址 2. 编译信息查看代码大小&#xff0c;修改代码后第一次编译后会有这个提示信息 2.1 修改代码后编译&#xff0c;会有提示…

ant-design-vue在ios使用AUpload组件唤起了相机,HTML的 `capture` 属性

在使用ant design vue组件的上传组件AUpload的时候有一个问题&#xff0c;直接按照demo写&#xff0c;在ios上会唤起相机&#xff0c;但是实际上我们的需求是弹出选择相册/相机这个弹框。 解决办法是加一个 cupture"null"这个属性即可 <a-upload:capture"nu…

注册中心Eureka和Nacos,以及负载均衡Ribbon

1.初识微服务 1.1.什么是微服务 微服务&#xff0c;就是把服务拆分成为若干个服务&#xff0c;降低服务之间的耦合度&#xff0c;提供服务的独立性和灵活性。做到高内聚&#xff0c;低耦合。 1.2.单体架构和微服务架构的区别&#xff1a; 单体架构&#xff1a;简单方便&#…

【后端必看】Redis 最佳实践

文章目录 1. Redis 键值设计1.1 优雅的 key 结构1.2 拒绝 BigKeyBigKey的危害如何发现BigKey①redis-cli --bigkeys② scan 扫描③第三方监控④网络监控 如何删除 BigKey 1.3 恰当的数据类型总结&#xff1a; 2. 批处理优化3. 服务器端优化-持久化配置4. 服务器端优化-慢查询优…

浅谈OCR中的David Shepard

在OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;中&#xff0c;David Shepard是一种早期的OCR技术&#xff0c;也被称为Shepards Method。 David Shepard是该OCR方法的原始作者。这种方法基于边界追踪算法&#xff0c;用于识别印刷体文本…

简单线性回归:预测事物间简单关系的利器

文章目录 &#x1f340;简介&#x1f340;什么是简单线性回归&#xff1f;&#x1f340;简单线性回归的应用场景使用步骤&#xff1a;注意事项&#xff1a; &#x1f340;代码演示&#x1f340;结论 &#x1f340;简介 在数据科学领域&#xff0c;线性回归是一种基本而强大的统…

关于视频监控平台EasyCVR视频汇聚平台建设“明厨亮灶”具体实施方案以及应用

一、方案背景 近几年来&#xff0c;餐饮行业的食品安全、食品卫生等新闻频频发生&#xff0c;比如某火锅店、某网红奶茶&#xff0c;食材以次充好、后厨卫生被爆堪忧&#xff0c;种种问题引起大众关注和热议。这些负面新闻不仅让餐饮门店的品牌口碑暴跌&#xff0c;附带的连锁…

postman测试后端增删改查

目录 一、本文介绍 二、准备工作 &#xff08;一&#xff09;新建测试 &#xff08;二&#xff09;默认url路径查看方法 三、增删改查 &#xff08;一&#xff09;查询全部 &#xff08;二&#xff09;增加数据 &#xff08;三&#xff09;删除数据 &#xff08;四&…

2022年电赛C题——小车跟随行驶系统——做题记录以及经验分享

前言 自己打算将做过的电赛真题&#xff0c;主要包含控制组的&#xff0c;近几年出现的小车控制题目&#xff0c;自己做过的真题以及在准备电赛期间刷真题出现的问题以及经验分享给大家 这次带来的是22年电赛C题——小车跟随行驶系统&#xff0c;这道题目指定使用的是TI的单片…

.Net程序调试时接受外部命令行参数方式

1.对项目右键&#xff0c;属性 2.在调试中打开常规&#xff0c;打开调试启动配置文件UI 3.输入需要的命令行参数

11. Docker Swarm(二)

1、前言 上一篇中我们利用Docker Swarm搭建了基础的集群环境。那么今天我们就来验证以下该集群的可用性。上一篇的示例中&#xff0c;我创建了3个实例副本&#xff0c;并且通过访问http://192.168.74.132:8080得到我们的页面。 2、验证高可用 1&#xff09;我们可以通过以下命…

【深度学习--RNN 循环神经网络--附LSTM情感文本分类】

deep learning 系列 --RNN 循环神经网络 什么是序列模型 包括了RNN LSTM GRU等网络模型&#xff0c;主要用途是自然语言处理、语音识别等方面&#xff0c;比如生成乐曲&#xff0c;音频转换为文字&#xff0c;文本情感分类&#xff0c;机器翻译等等 标准模型的缺陷 以往的标…

基于ArcGis提取道路中心线

基于ArcGis提取道路中心线 文章目录 基于ArcGis提取道路中心线前言一、生成缓冲区二、导出栅格数据三、导入栅格数据四、新建中心线要素五、生成中心线总结 前言 最近遇到一个问题&#xff0c;根据道路SHP数据生成模型的时候由于下载的道路数据杂项数据很多&#xff0c;所以导…

windows server 2016 搭建使用 svn 服务器教程

参考教程&#xff1a; https://zhuanlan.zhihu.com/p/428552058 https://blog.csdn.net/weixin_33897722/article/details/85602029 配置环境 windows server 2016 远程服务器公网 ip 安装 SVN 服务端 下载 svn 服务端安装包&#xff1a;https://www.visualsvn.com/download…

Python Web框架:Django、Flask和FastAPI巅峰对决

今天&#xff0c;我们将深入探讨Python Web框架的三巨头&#xff1a;Django、Flask和FastAPI。无论你是Python小白还是老司机&#xff0c;本文都会为你解惑&#xff0c;带你领略这三者的魅力。废话不多说&#xff0c;让我们开始这场终极对比&#xff01; Django&#xff1a;百…

Vue 项目运行 npm install 时,卡在 sill idealTree buildDeps 没有反应

解决方法&#xff1a;切换到淘宝镜像。 以下是之前安装的 xmzs 包&#xff0c;用于控制切换淘宝镜像。 该截图是之前其他项目切换淘宝镜像的截图。 切换镜像后&#xff0c;顺利执行 npm install 。

基于令牌级 BERT 嵌入的趋势生成句子级嵌入

一、说明 句子&#xff08;短语或段落&#xff09;级别嵌入通常用作许多 NLP 分类问题的输入&#xff0c;例如&#xff0c;在垃圾邮件检测和问答 &#xff08;QA&#xff09; 系统中。在我上一篇文章发现不同级别的BERT嵌入的趋势中&#xff0c;我讨论了如何生成一个向量表示&a…

docker安装国产开源数据库tidb 单机版

docker pull pingcap/tidb 创建目录&#xff0c;然后安装tidb mkdir -p /data/tidb/data 创建容器 docker run --name tidb -d -v /data/tidb/data:/tmp/tidb --privilegedtrue -p 4000:4000 -p 10080:10080 pingcap/tidb:latest TiDB 简介 | PingCAP 文档中心

LabVIEW使用图像处理进行交通控制性能分析

LabVIEW使用图像处理进行交通控制性能分析 采用普雷维特、拉普拉斯、索贝尔和任意的空间域方法对存储的图像进行边缘检测&#xff0c;并获取实时图像。然而&#xff0c;对四种不同空间域边缘检测方法的核的性能分析。 以前&#xff0c;空路图像存储在数据库中&#xff0c;道路…

Python 使用Hadoop 3 之HDFS 总结

Hadoop 概述 Hadoop 是一个由Apache 软件基金会开发的分布式基础架构。用户可以在不了解分布式底层细节的情况下&#xff0c;开发分布式程序&#xff0c;充分利用集群的威力进行高速运算和存储。 Hadoop 实现一个分布式文件系统&#xff08;Hadoop Distributed File Sy…