【2】STM32·FreeRTOS·任务创建和删除

目录

一、任务创建和删除的API函数

1.1、动态创建任务函数

1.2、静态创建任务函数

1.3、任务删除函数

二、任务创建和删除(动态方法)

三、任务创建和删除(静态方法)


一、任务创建和删除的API函数

任务的创建和删除本质就是调用 FreeRTOS 的 API 函数

API函数描述

xTaskCreate()

动态方式创建任务
xTaskCreateStatic()静态方式创建任务
xTaskDelete()删除任务

动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配

静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供

1.1、动态创建任务函数

BaseType_t xTaskCreate
(TaskFunction_t                  pxTaskCode,      /* 指向任务函数的指针 */const char * const              pcName,          /* 任务名字,最大长度configMAX_TASK_NAME_LEN */const configSTACK_DEPTH_TYPE    usStackDepth,    /* 任务堆栈大小,注意字为单位 */void * const                    pvParameters,    /* 传递给任务函数的参数 */UBaseType_t                     uxPriority,      /* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */TaskHandle_t * const            pxCreatedTask    /* 任务句柄,就是任务的任务控制块 */
)
返回值描述
pdPASS任务创建成功

errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY

任务创建失败

实现动态创建任务流程

1、将宏 configSUPPORT_DYNAMIC_ALLOCATION 配置为 1

2、定义函数入口参数

3、编写任务函数

此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

动态创建任务函数内部实现

1、申请堆栈内存&任务控制块内存

2、TCB结构体成员赋值

3、添加新任务到就绪列表中

任务控制块结构体成员介绍

typedef struct tskTaskControlBlock
{volatile StackType_t      *pxTopOfStack;                           /* 任务栈栈顶,必须为TCB的第一个成员 */ListItem_t                xStateListItem;                          /* 任务状态列表项 */ListItem_t                xEventListItem;                          /* 任务事件列表项 */UBaseType_t               uxPriority;                              /* 任务优先级,数值越大,优先级越大 */StackType_t               *pxStack;                                /* 任务栈起始地址 */char                      pcTaskName[configMAX_TASK_NAME_LEN];     /* 任务名字 */...
} tskTCB;

任务栈栈顶,在任务切换时的任务上下文保存、任务恢复息息相关

每个任务都有属于自己的任务控制块,类似身份证

1.2、静态创建任务函数

TaskHandle_t xTaskCreateStatic
(TaskFunction_t          pxTaskCode,        /* 指向任务函数的指针 */const char * const      pcName,            /* 任务函数名 */const uint32_t          ulStackDepth,      /* 任务堆栈大小,注意字为单位 */void * const            pvParameters,      /* 传递给任务函数的参数 */UBaseType_t             uxPriority,        /* 任务优先级 */StackType_t * const     puxStackBuffer,    /* 任务堆栈,一般为数组,由用户分配 */StaticTask_t * const    pxTaskBuffer       /* 任务控制块指针,由用户分配 */
)
返回值描述
NULL用户没有提供相应的内存,任务创建失败

其他值

任务句柄,任务创建成功

静态创建任务使用流程

1、将宏 configSUPPORT_STATIC_ALLOCATION 配置为 1

2、定义空闲任务&定时器任务的任务堆栈及TCB

3、实现两个接口函数:vApplicationGetIdleTaskMemory()、vApplicationGetTimerTaskMemory()

4、定义函数入口参数

5、编写任务函数

此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

静态创建任务函数内部实现

1、TCB结构体成员赋值

2、添加新任务到就绪列表中

1.3、任务删除函数

void vTaskDelete(TaskHandle_t xTaskToDelete);
形参描述
xTaskToDelete待删除任务的任务句柄

用于删除已被创建的任务,被删除的任务将从就绪态任务列表阻塞态任务列表挂起态任务列表事件列表中移除

1、当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)

2、当要删除任务自身时,空闲任务会负责释放被删除任务中由系统分配的内存(动态创建任务),但是由用户在任务删除前申请的内存(静态创建任务),则需要由用户在任务被删除前提前释放,否则将导致内存泄漏

删除任务流程

1、使用删除任务函数,需将宏 INCLUDE_vTaskDelete 配置为 1

2、入口参数输入需要删除的任务句柄(NULL代表删除本身)

删除任务函数内部实现

1、获取所要删除任务的控制块:通过传入的任务句柄,判断所需要删除哪个任务,NULL代表删除自身

2、将被删除任务,移除所在列表:将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表

3、判断所需要删除的任务:删除任务自身,需先添加到等待删除列表,内存释放将在空闲任务执行。删除其他任务,释放内存,任务数量

4、更新下个任务的阻塞时间:更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务

二、任务创建和删除(动态方法)

将设计四个任务:start_task、task1、task2、task3

四个任务的功能如下

start_task:用来创建其他三个任务

task1:实现 LED0 每 500ms 闪烁一次

task2:实现 LED0 每 500ms 闪烁一次

task3:判断按键 KEY0 是否按下,按下则删掉 task1

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "freertos_demo.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */delay_init(168);                    /* 延时初始化 */usart_init(115200);                 /* 串口初始化为115200 */led_init();                         /* 初始化LED */lcd_init();                         /* 初始化LCD */key_init();                         /* 初始化按键 */freertos_demo();
}

freertos_demo.c

#include "freertos_demo.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1            /* 任务优先级 */
#define START_STK_SIZE 128           /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler;      /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 *//* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO 2            /* 任务优先级 */
#define TASK1_STK_SIZE 128      /* 任务堆栈大小 */
TaskHandle_t Task1Task_Handler; /* 任务句柄 */
void task1(void *pvParameters); /* 任务函数 *//* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO 3            /* 任务优先级 */
#define TASK2_STK_SIZE 128      /* 任务堆栈大小 */
TaskHandle_t Task2Task_Handler; /* 任务句柄 */
void task2(void *pvParameters); /* 任务函数 *//* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO 4            /* 任务优先级 */
#define TASK3_STK_SIZE 128      /* 任务堆栈大小 */
TaskHandle_t Task3Task_Handler; /* 任务句柄 */
void task3(void *pvParameters); /* 任务函数 *//******************************************************************************************************//* LCD刷屏时使用的颜色 */
uint16_t lcd_discolor[11] = {WHITE, BLACK, BLUE, RED,MAGENTA, GREEN, CYAN, YELLOW,BROWN, BRRED, GRAY};/* FreeRTOS例程入口函数 */
void freertos_demo(void)
{lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);lcd_show_string(10, 47, 220, 24, 24, "Task Create & Del", RED);lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);lcd_draw_rectangle(5, 110, 115, 314, BLACK);lcd_draw_rectangle(125, 110, 234, 314, BLACK);lcd_draw_line(5, 130, 115, 130, BLACK);lcd_draw_line(125, 130, 234, 130, BLACK);lcd_show_string(15, 111, 110, 16, 16, "Task1: 000", BLUE);lcd_show_string(135, 111, 110, 16, 16, "Task2: 000", BLUE);xTaskCreate((TaskFunction_t)start_task,          /* 任务函数 */(const char *)"start_task",          /* 任务名称 */(uint16_t)START_STK_SIZE,            /* 任务堆栈大小 */(void *)NULL,                        /* 传入给任务函数的参数 */(UBaseType_t)START_TASK_PRIO,        /* 任务优先级 */(TaskHandle_t *)&StartTask_Handler); /* 任务句柄 */vTaskStartScheduler();
}/* start_task */
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); /* 进入临界区 *//* 创建任务1 */xTaskCreate((TaskFunction_t)task1,               /* 任务函数 */(const char *)"task1",               /* 任务名称 */(uint16_t)TASK1_STK_SIZE,            /* 任务堆栈大小 */(void *)NULL,                        /* 传入给任务函数的参数 */(UBaseType_t)TASK1_PRIO,             /* 任务优先级 */(TaskHandle_t *)&Task1Task_Handler); /* 任务句柄 *//* 创建任务2 */xTaskCreate((TaskFunction_t)task2,               /* 任务函数 */(const char *)"task2",               /* 任务名称 */(uint16_t)TASK2_STK_SIZE,            /* 任务堆栈大小 */(void *)NULL,                        /* 传入给任务函数的参数 */(UBaseType_t)TASK2_PRIO,             /* 任务优先级 */(TaskHandle_t *)&Task2Task_Handler); /* 任务句柄 *//* 创建任务3 */xTaskCreate((TaskFunction_t)task3,               /* 任务函数 */(const char *)"task3",               /* 任务名称 */(uint16_t)TASK3_STK_SIZE,            /* 任务堆栈大小 */(void *)NULL,                        /* 传入给任务函数的参数 */(UBaseType_t)TASK3_PRIO,             /* 任务优先级 */(TaskHandle_t *)&Task3Task_Handler); /* 任务句柄 */vTaskDelete(StartTask_Handler);                  /* 删除开始任务 */taskEXIT_CRITICAL();                             /* 退出临界区 */
}/* task1 */
void task1(void *pvParameters)
{uint32_t task1_num = 0;while (1){lcd_fill(6, 131, 114, 313, lcd_discolor[++task1_num % 11]);lcd_show_xnum(71, 111, task1_num, 3, 16, 0x80, BLUE);LED0_TOGGLE();vTaskDelay(500);}
}/* task2 */
void task2(void *pvParameters)
{uint32_t task2_num = 0;while (1){lcd_fill(126, 131, 233, 313, lcd_discolor[11 - (++task2_num % 11)]);lcd_show_xnum(191, 111, task2_num, 3, 16, 0x80, BLUE);LED1_TOGGLE();vTaskDelay(500);}
}/* task3 */
void task3(void *pvParameters)
{uint8_t key = 0;while (1){key = key_scan(0);switch (key){case KEY0_PRES: /* 删除任务1 */{if (Task1Task_Handler != NULL){vTaskDelete(Task1Task_Handler);Task1Task_Handler = NULL;}break;}case KEY1_PRES: /* 删除任务2 */{if (Task2Task_Handler != NULL){vTaskDelete(Task2Task_Handler);Task2Task_Handler = NULL;}break;}default:{break;}}vTaskDelay(10);}
}

freertos_demo.h

#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/LCD/lcd.h"
#include "FreeRTOS.h"
#include "task.h"void freertos_demo(void);#endif

三、任务创建和删除(静态方法)

将设计四个任务:start_task、task1、task2、task3

四个任务的功能如下

start_task:用来创建其他三个任务

task1:实现 LED0 每 500ms 闪烁一次

task2:实现 LED0 每 500ms 闪烁一次

task3:判断按键 KEY0 是否按下,按下则删掉 task1

main.c、freertos_demo.h 和动态创建一样

freertos_demo.c

#include "freertos_demo.h"/******************************************************************************************************/
/*FreeRTOS配置*/static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];      /* 空闲任务任务堆栈 */
static StaticTask_t IdleTaskTCB;                                 /* 空闲任务控制块 */
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH]; /* 定时器服务任务堆栈 */
static StaticTask_t TimerTaskTCB;                                /* 定时器服务任务控制块 *//*** @brief       获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该有用户来提供,FreeRTOS提供了接口函数vApplicationGetIdleTaskMemory()实现此函数即可。* @param       ppxIdleTaskTCBBuffer:任务控制块内存ppxIdleTaskStackBuffer:任务堆栈内存pulIdleTaskStackSize:任务堆栈大小* @retval      无*/
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,StackType_t **ppxIdleTaskStackBuffer,uint32_t *pulIdleTaskStackSize)
{*ppxIdleTaskTCBBuffer = &IdleTaskTCB;*ppxIdleTaskStackBuffer = IdleTaskStack;*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}/*** @brief       获取定时器服务任务的任务堆栈和任务控制块内存* @param       ppxTimerTaskTCBBuffer:任务控制块内存ppxTimerTaskStackBuffer:任务堆栈内存pulTimerTaskStackSize:任务堆栈大小* @retval      无*/
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,StackType_t **ppxTimerTaskStackBuffer,uint32_t *pulTimerTaskStackSize)
{*ppxTimerTaskTCBBuffer = &TimerTaskTCB;*ppxTimerTaskStackBuffer = TimerTaskStack;*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}/* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE 128                  /* 任务堆栈大小 */
StackType_t StartTaskStack[START_STK_SIZE]; /* 任务堆栈 */
StaticTask_t StartTaskTCB;                  /* 任务控制块 */
TaskHandle_t StartTask_Handler;             /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 *//* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO 2                        /* 任务优先级 */
#define TASK1_STK_SIZE 128                  /* 任务堆栈大小 */
StackType_t Task1TaskStack[TASK1_STK_SIZE]; /* 任务堆栈 */
StaticTask_t Task1TaskTCB;                  /* 任务控制块 */
TaskHandle_t Task1Task_Handler;             /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 *//* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO 3                        /* 任务优先级 */
#define TASK2_STK_SIZE 128                  /* 任务堆栈大小 */
StackType_t Task2TaskStack[TASK2_STK_SIZE]; /* 任务堆栈 */
StaticTask_t Task2TaskTCB;                  /* 任务控制块 */
TaskHandle_t Task2Task_Handler;             /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 *//* TASK3 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK3_PRIO 4                        /* 任务优先级 */
#define TASK3_STK_SIZE 128                  /* 任务堆栈大小 */
StackType_t Task3TaskStack[TASK3_STK_SIZE]; /* 任务堆栈 */
StaticTask_t Task3TaskTCB;                  /* 任务控制块 */
TaskHandle_t Task3Task_Handler;             /* 任务句柄 */
void task3(void *pvParameters);             /* 任务函数 *//******************************************************************************************************//* LCD刷屏时使用的颜色 */
uint16_t lcd_discolor[11] = {WHITE, BLACK, BLUE, RED,MAGENTA, GREEN, CYAN, YELLOW,BROWN, BRRED, GRAY};/* FreeRTOS例程入口函数 */
void freertos_demo(void)
{lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);lcd_show_string(10, 47, 220, 24, 24, "Task Create & Del", RED);lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);lcd_draw_rectangle(5, 110, 115, 314, BLACK);lcd_draw_rectangle(125, 110, 234, 314, BLACK);lcd_draw_line(5, 130, 115, 130, BLACK);lcd_draw_line(125, 130, 234, 130, BLACK);lcd_show_string(15, 111, 110, 16, 16, "Task1: 000", BLUE);lcd_show_string(135, 111, 110, 16, 16, "Task2: 000", BLUE);StartTask_Handler = xTaskCreateStatic((TaskFunction_t)start_task,     /* 任务函数 */(const char *)"start_task",     /* 任务名称 */(uint32_t)START_STK_SIZE,       /* 任务堆栈大小 */(void *)NULL,                   /* 传递给任务函数的参数 */(UBaseType_t)START_TASK_PRIO,   /* 任务优先级 */(StackType_t *)StartTaskStack,  /* 任务堆栈 */(StaticTask_t *)&StartTaskTCB); /* 任务控制块 */vTaskStartScheduler();
}/* start_task */
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); /* 进入临界区 *//* 创建任务1 */Task1Task_Handler = xTaskCreateStatic((TaskFunction_t)task1,          /* 任务函数 */(const char *)"task1",          /* 任务名称 */(uint32_t)TASK1_STK_SIZE,       /* 任务堆栈大小 */(void *)NULL,                   /* 传递给任务函数的参数 */(UBaseType_t)TASK1_PRIO,        /* 任务优先级 */(StackType_t *)Task1TaskStack,  /* 任务堆栈 */(StaticTask_t *)&Task1TaskTCB); /* 任务控制块 *//* 创建任务2 */Task2Task_Handler = xTaskCreateStatic((TaskFunction_t)task2,          /* 任务函数 */(const char *)"task2",          /* 任务名称 */(uint32_t)TASK2_STK_SIZE,       /* 任务堆栈大小 */(void *)NULL,                   /* 传递给任务函数的参数 */(UBaseType_t)TASK2_PRIO,        /* 任务优先级 */(StackType_t *)Task2TaskStack,  /* 任务堆栈 */(StaticTask_t *)&Task2TaskTCB); /* 任务控制块 *//* 创建任务3 */Task3Task_Handler = xTaskCreateStatic((TaskFunction_t)task3,          /* 任务函数 */(const char *)"task3",          /* 任务名称 */(uint32_t)TASK3_STK_SIZE,       /* 任务堆栈大小 */(void *)NULL,                   /* 传递给任务函数的参数 */(UBaseType_t)TASK3_PRIO,        /* 任务优先级 */(StackType_t *)Task3TaskStack,  /* 任务堆栈 */(StaticTask_t *)&Task3TaskTCB); /* 任务控制块 */vTaskDelete(StartTask_Handler);                                       /* 删除开始任务 */taskEXIT_CRITICAL();                                                  /* 退出临界区 */
}/* task1 */
void task1(void *pvParameters)
{uint32_t task1_num = 0;while (1){lcd_fill(6, 131, 114, 313, lcd_discolor[++task1_num % 11]);lcd_show_xnum(71, 111, task1_num, 3, 16, 0x80, BLUE);LED0_TOGGLE();vTaskDelay(500);}
}/* task2 */
void task2(void *pvParameters)
{uint32_t task2_num = 0;while (1){lcd_fill(126, 131, 233, 313, lcd_discolor[11 - (++task2_num % 11)]);lcd_show_xnum(191, 111, task2_num, 3, 16, 0x80, BLUE);LED1_TOGGLE();vTaskDelay(500);}
}/* task3 */
void task3(void *pvParameters)
{uint8_t key = 0;while (1){key = key_scan(0);switch (key){case KEY0_PRES: /* 删除任务1 */{if (Task1Task_Handler != NULL){vTaskDelete(Task1Task_Handler);Task1Task_Handler = NULL;}break;}case KEY1_PRES: /* 删除任务2 */{if (Task2Task_Handler != NULL){vTaskDelete(Task2Task_Handler);Task2Task_Handler = NULL;}break;}default:{break;}}vTaskDelay(10);}
}

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

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

相关文章

Flutter笔记:手动配置VSCode中Dart代码自动格式化

Flutter笔记 手动配置VSCode中Dart代码自动格式化 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csd…

数据结构学习——线性表、顺序表

1.线性表 线性表 ( linear list ) 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一…

在WPS表格(Excel)中,每10行增加一个特定的值

注:如下为WPS表格操作演示 例如1-15的数值是1,16-30就变为2,31-45就变为3,类推! 1、在B1单元格输入一个起始值,B2单元格输入公式IF(MOD(ROW(),15)0,B11,B1) 然后鼠标放到B2单元格右下角小点处&…

利用生成式AI重新构想ITSM的未来

对注入 AI 的生成式 ITSM 的需求,在 2023 年 Gartner AI 炒作周期中,生成式 AI 达到预期值达到顶峰后,三分之二的企业已经将生成式 AI 集成到其流程中。 你问为什么这种追求?在预定义算法的驱动下,IT 服务交付和管理中…

第七届机电、机器人与自动化国际会议(ICMRA 2024)即将召开!

第七届机电、机器人与自动化国际会议(ICMRA 2024)将于2024年9月20日-22日在中国武汉举行。ICMRA 2024为各国专家学者提供一个学术交流的平台,讨论机电、机器人和自动化领域的最新研究成果和未来的研究方向,旨在能够建立起国家间&a…

Ansible剧本playbook之--------Templates 模块、roles角色详细解读

目录 一、Templates 模块 1.1准备模板文件并设置引用的变量 1.2修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量 1.3编写 playbook 1.4ansible主机远程查看修改参数 1.5验证 二、tags 模块 always应用 三、Roles 模块 3.1ro…

在国企分公司做信息宣传新闻投稿的经验分享

作为一名国企分公司的信息宣传工作者,我亲历了从传统投稿方式到数字化转型的全过程,这段经历既充满了挑战,也收获了成长。回首最初的日子,那些用邮箱投稿的时光,至今仍让我感慨万千。 初尝辛酸,邮箱投稿的艰难岁月 刚接手信息宣传工作时,我满腔热情,却很快被现实的冷水浇了个透…

RabbitMQ的五种模式

一、简单模式 简单模式(Simple):一个生产者,一个消费者 package com.qiangesoft.rabbitmq.mode.simple;import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.Queue; import org.springframe…

事业单位向媒体投稿发文章上级领导交给了我投稿方法

作为一名事业单位的普通职员,负责信息宣传工作,我见证了从传统投稿方式到智能化转型的全过程,这段旅程既是一次挑战,也是一次宝贵的成长。回想起初涉此领域的日子,那些通过邮箱投稿的时光,至今仍然历历在目,其中的酸甜苦辣,构成了我职业生涯中一段难忘的经历。 邮箱投稿:费时费…

C++从入门到精通---模版

文章目录 泛型编程函数模版模版参数的匹配原则类模版类模版的定义格式类模版的实例化 总结 泛型编程 泛型编程是一种编程范式,旨在实现通用性和灵活性。它允许在编写代码时使用参数化类型,而不是具体的类型,从而使代码更加灵活和可重用。 在…

spring ioc 容器加载过程 refresh() 方法详解

IOC 加载过程 从 new ClassPathXmlApplicationContext开始 ApplicationContext context new ClassPathXmlApplicationContext("classpath:application.xml");ClassPathXmlApplicationContext类构造方法 public ClassPathXmlApplicationContext(String[] configLo…

Redis集群分片

什么是集群 集群是由多个复制集组成的,能提供在多个redis节点间共享数据的程序集 简而言之就是将原来的单master主机拆分为多个master主机,将整个数据集分配到各主机上 集群的作用 集群中可以存在多个master,而每个master可以挂载多个slave自带哨兵的故障转移机制,不需要再去…

Python解释器3.8.2版本安装详细教程

Python解释器提取链接链接: https://pan.baidu.com/s/1eDvwYmUJ4l7kIBXewtN4EA?pwd1111 提取码:1111 演示版本为3.6.8,链接安装包为3.8.2版,包中附加pytharm安装包。 1.双击提取好的python-exe安装文件,会…

外企接受大龄程序员吗?

本人知乎账号同公众号:老胡聊Java,欢迎留言并咨询 亲身体会外企经历所见所闻,外企能接受大龄程序员。 1 大概是10年的时候,进一家知名外企,和我一起进的一位manager,后来听下来,年龄35&#xf…

0508_IO3

练习1&#xff1a; 1&#xff1a;使用 dup2 实现错误日志功能 使用 write 和 read 实现文件的拷贝功能&#xff0c;注意&#xff0c;代码中所有函数后面&#xff0c;紧跟perror输出错误信息&#xff0c;要求这些错误信息重定向到错误日志 err.txt 中去 1 #include <stdio.h…

【matlab基础知识代码】(十二)逆矩阵与广义逆矩阵

>> Hhilb(4);H1inv(H),norm(H*H1-eye(4))H1 1.0e03 *0.0160 -0.1200 0.2400 -0.1400-0.1200 1.2000 -2.7000 1.68000.2400 -2.7000 6.4800 -4.2000-0.1400 1.6800 -4.2000 2.8000ans 2.8455e-13 矩阵维数较大&#xff0c;警告: 矩阵接近奇…

svg画扇形进度动画

有人问下面这种图好怎么画&#xff1f;svg 想了下&#xff0c;确实用svg可以&#xff0c;可以这么设计 外层是一个容器放置内容&#xff0c;并且设置overflow:hidden&#xff0c; 内层放一个半径大于容器宽高一半的svg&#xff0c;并定位居中&#xff0c;然后svg画扇形&#x…

线程的组成、执行特点、创建的两种方式

线程的组成&#xff1a; cpu时间片 运行内存&#xff1a;栈、堆 线程的逻辑代码 线程执行的特点&#xff1a; 抢占式执行&#xff0c;结果随机&#xff0c;效率高&#xff0c;可以防止单一线程长时间独占CPU 在单核cpu中&#xff0c;宏观上同时执行&#xff0c;微观上顺序…

C++青少年简明教程之一:基础知识

C青少年简明教程之一&#xff1a;基础知识 电脑程序设计&#xff08;Computer programming&#xff09;&#xff0c;或称程序设计&#xff08;programming&#xff09;&#xff0c;是给出解决特定问题程序的过程&#xff0c;程序设计往往以某种程序设计语言为工具&#xff0c;给…

【软件测试】用例篇 -- 详解

一、测试用例的基本要素 测试用例&#xff08;Test Case&#xff09;是为了实施测试而向被测试的系统提供的一组集合&#xff0c;这组集合包含&#xff1a;测试环境、操作步骤、测试数据、预期结果等要素。&#xff08;注意&#xff1a;不需要执行结果&#xff0c;因为执行结果…