当前位置: 首页 > news >正文

ESP32学习笔记_FreeRTOS(6)——Event and Notification

摘要(From AI):
这篇博客详细介绍了 FreeRTOS 中的事件组和任务通知机制,讲解了事件组如何通过位操作实现任务间的同步与通信,以及任务如何通过通知机制进行阻塞解除和数据传递。博客提供了多个代码示例,展示了如何使用事件组和任务通知在多任务环境中实现任务同步,特别适用于任务间的依赖关系和信号传递

前言:本文档是本人在依照B站UP:Michael_ee的视频教程进行学习时所做的学习笔记,可能存在疏漏和错误,如有发现,敬请指正。

文章目录

    • Event Group
      • Event Group Wait
        • xEventGroupCreate()
        • xEventGroupSetBits()
        • xEventGroupWaitBits()
        • Example Code:Event Group Synchronization with Multiple Tasks
      • Event Group Sync
        • xEventGroupSync()
        • Example Code:Event Group Synchronization
    • Notification
      • Notification Sync
        • xTaskNotifyGive()
        • ulTaskNotifyTake()
        • Example Code:Simple Task Notification in FreeRTOS
      • Notification Value
        • xTaskNotify()
        • xTaskNotifyWait()
        • Example Code:Task Notification with Conditional Actions Based on Values

参考资料
Michael_ee 视频教程
freeRTOS官网
espressif 在线文档


Event Group

事件组是一种同步机制,用于任务之间的通信。它们允许任务设置、清除和等待多个事件的组合

每个事件组有多个位,任务可以操作这些位来表示不同的状态或事件。

关键功能

  • 位操作​事件组可以被看作是一个二进制位的集合,任务可以对这些位进行设置、清除和等待
  • 同步机制​任务可以等待事件组中的某些位变为设定状态(例如,位为1),这样可以使任务在等待某些事件发生时暂停执行,直到事件发生
  • 多任务通信​事件组可以在多个任务之间传递信息

使用场景

  • 在多个任务之间传递控制信号或数据标志
  • 实现任务之间的依赖关系,如任务A完成某项工作后,任务B才可以执行

Event Group Wait

xEventGroupCreate()

创建一个新的事件组,并返回可以引用创建的事件组的句柄

事件组包含的标志位(或位)的数量依赖于 configUSE_16_BIT_TICKS​ 配置项

  • 如果 configUSE_16_BIT_TICKS = 1​,则事件组有 8 位(标志位)

  • 如果 configUSE_16_BIT_TICKS = 0​,则事件组有 24 位(标志位)

  • 配置文件路径(v5.3.1)idf\v5.3.1\esp-idf\components\freertos\config\include\freertos

#include "FreeRTOS.h"
#include "event_groups.h"EventGroupHandle_t xEventGroupCreate( void );

返回值

EventGroupHandle_t​创建了事件组,返回的值是创建的事件组的句柄

NULL​无法创建事件组,因为可用的 FreeRTOS 堆内存不足

xEventGroupSetBits()

在RTOS事件组中设置位

  • 这个函数不能从中断中调用
#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet );

参数

xEventGroup​需要设置 bit 的事件组

uxBitsToSet​一个按位的值,表示要在事件组中设置的一个或多个位

  • 通过设置不同的二进制值来指定要等待的位

    • 如果想等待 bit 0 和 bit 2 设置,uxBitsToWaitFor​ 应该是 0x05​(即 00000101​)
    • 如果想等待 bit 0、bit 1 和 bit 2 设置,uxBitsToWaitFor​ 应该是 0x07​(即 00000111​)
  • 可以根据需求组合多个位来构造不同的掩码值

返回值

EventBits_t​事件组中各位(bits)在调用 xEventGroupSetBits()​ 函数返回时的状态

可能被改变状态的情况

  1. 自动清除(xClearBitsOnExit​ 参数

    1. 当调用 xEventGroupSetBits()​ 设置位后,可能有任务正在等待这些位(通过 xEventGroupWaitBits()​),如果等待任务设置了 xClearBitsOnExit​ 参数为 pdTRUE​,则这些位在任务被唤醒时会自动被清除,在 xEventGroupSetBits()​ 返回时,返回值中的位可能已经被清除
  2. 高优先级 Task 清除位

    1. 如果设置事件位后,有更高优先级的任务因这些位的设置从阻塞状态切换为就绪状态(Ready),并立即执行,它可能会修改事件组的值

xEventGroupSetBits()​ 返回时,返回值可能反映的是任务执行后事件组的状态,而不是立即设置位后的状态

xEventGroupWaitBits()

读取RTOS事件组中的位,可选择进入阻塞状态(带超时)以等待一个位或一组位被设置

  • 这个函数不能从中断中调用
#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );

参数

xEventGroup​需要测试(查看)bit 的事件组

uxBitsToWaitFor​一个位运算值,用于指定在事件组中要等待的位

  • 不能被设置为0

xClearOnExit​设置是否清除事件

  • pdTRUE

    • 如果设置为 pdTRUE​,那么在函数返回时,事件组中由 uxBitsToWaitFor指定的那些位会被清除(即设置为 0),前提是函数返回的原因不是超时
    • 这通常用于在检测到某些事件发生后,自动清除事件状态,避免其他任务误判这些事件仍然有效。
  • pdFALSE

    • 如果设置为 pdFALSE​,事件组中的位不会被清除,即便函数成功返回。这种方式适用于需要让其他任务也能检测到这些位的场景

xWaitForAllBits​决定任务等待位时的逻辑条件是 逻辑 AND(等待所有指定的位都被设置)还是 逻辑 OR(只需等待任意一个指定的位被设置)

  • pdTRUE​(逻辑 AND)

    • 函数会等待事件组中的所有指定位都被设置为 1
    • 如果所有位在等待时间内都被设置,函数返回
    • 如果等待时间到期(xTicksToWait​ 超时),函数返回超时结果
  • pdFALSE​(逻辑 OR)

    • 函数会等待事件组中的任意一个指定位被设置为 1
    • 如果任意一位在等待时间内被设置,函数立即返回
    • 如果等待时间到期且没有任何位被设置,函数返回超时结果

xTicksToWait​等待一个/全部 bit 的最大时间

返回值

EventBits_t​事件组的当前值,这个值表示函数返回时,事件组中哪些位(bits)是被设置(1)的

Example Code:Event Group Synchronization with Multiple Tasks
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"EventGroupHandle_t eventGroup;#define BIT_0 (1 << 0)
#define BIT_4 (1 << 4)void Task1(void *pvParam)
{printf("Task1 is running\n");while (true){printf("Task1 is begin to wait\n");// xEventGroupWaitBits(eventGroup, BIT_0 | BIT_4, pdTRUE, pdFALSE, portMAX_DELAY);// // 检测第一位和第四位是否被设置,如果设置则唤醒Task1// // 检测完成后,第一位和第四位将被清除// printf("BIT_0 or BIT_4 is set, Task1 is woken up\n");xEventGroupWaitBits(eventGroup, BIT_0 | BIT_4, pdTRUE, pdTRUE, portMAX_DELAY);printf("BIT_0 or BIT_4 is set, Task1 is woken up\n");vTaskDelay(pdMS_TO_TICKS(1000));}
}void Task2(void *pvParam)
{printf("Task2 is running\n");vTaskDelay(pdMS_TO_TICKS(1000));while (true){printf("Task2 is begin to set bit0\n");xEventGroupSetBits(eventGroup, BIT_0);vTaskDelay(pdMS_TO_TICKS(5000));printf("Task2 is begin to set bit4\n");xEventGroupSetBits(eventGroup, BIT_4);vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{eventGroup = xEventGroupCreate(); // 创建事件组if (eventGroup == NULL){printf("Event group creation failed\n");}else{vTaskSuspendAll();xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task2, "Task2", 2048, NULL, 1, NULL, 0);xTaskResumeAll();}
}

Event Group Sync

wait​和sync​的不同:

wait

等待事件组的 Task(设为 waitTask) 在进入 wait 状态后,等待设置事件组的 Task(设为 setTask)对事件组进行设置,waitTask 在检测到事件组满足要求后继续运行,setTask 在调用xEventGroupSetBits()​后不阻塞,继续运行

sync

setTask 在设置事件组的目标位后进入阻塞状态,等待其它 setTask 对事件组进行设置,当满足各 setTask 对事件组的要求后,所有进入阻塞状态的 setTask 同时进入运行状态

即 setTask 在设置事件组之后也在 wait 事件组

xEventGroupSync()

在事件组中设置位,然后等待在同一事件组中设置位的组合

此功能通常用于同步多个任务(通常称为任务集合),其中每个任务在继续之前必须等待其他任务到达同步点

如果uxBitsToWaitFor​参数指定的位被设置或在该时间内被设置,则该函数将在其时间到期之前返回,这种情况下,由uxBitsToWaitFor​指定的所有位将在函数返回之前自动清除

这个函数不能从中断中调用

#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait );

参数

xEventGroup​需要设置 bit 的时间组

uxBitsToSet​一个位运算值,用于指定在事件组中要设置的位

uxBitsToWaitFor​一个位运算值,用于指定在事件组中要等待的位

xTicksToWait​等待 bits 的最大时间

返回值

EventBits_t​表示事件组的状态,具体包括以下两种情况:

  1. 等待的位被设置

    • 如果 xEventGroupSync()​ 返回是因为所有等待的位被设置,则返回值是事件组中这些位在被清除前的状态
  2. 超时到期

    • 如果 xEventGroupSync()​ 返回是因为超时时间到期,则可能并非所有等待的位都被设置,返回值表示超时时事件组的状态

Example Code:Event Group Synchronization
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"EventGroupHandle_t eventGroup;#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)
#define BIT_2 (1 << 2)
#define ALL_SYNC_BITS (BIT_0 | BIT_1 | BIT_2)void Task0(void *pvParam)
{printf("Task0 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(1000));printf("Task0 set BIT_0\n");xEventGroupSync(eventGroup, BIT_0, ALL_SYNC_BITS, portMAX_DELAY); // 设置 BIT_0,进入同步等待printf("Task0 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(3000));printf("Task1 set BIT_1\n");xEventGroupSync(eventGroup, BIT_1, ALL_SYNC_BITS, portMAX_DELAY);printf("Task1 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void Task2(void *pvParam)
{printf("Task2 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(6000));printf("Task2 set BIT_2\n");xEventGroupSync(eventGroup, BIT_2, ALL_SYNC_BITS, portMAX_DELAY);printf("Task2 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{eventGroup = xEventGroupCreate(); // 创建事件组if (eventGroup == NULL){printf("Event group creation failed\n");}else{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task2, "Task2", 2048, NULL, 1, NULL, 0);xTaskResumeAll();}
}

Notification

每个任务都有一个 32 位的通知值,该值在任务创建时初始

任务通知是直接发送给任务的事件,它可以解除接收任务的阻塞,并可选择更新接收任务的通知值

通知值有两种用法:按位、增量

Notification Sync

xTaskNotifyGive()

使目标任务的通知值递增

  • RTOS 任务通知功能在默认情况下是启用的,并且可以从构建中排除(每个任务节省8字节)通过在 FreeRTOSConfig.h​ 设置configUSE_TASK_NOTIFICATIONS​为0
#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );

参数

xTaskToNotify​被通知的任务的句柄,其通知值递增(增量用法

返回值

总是返回pdPASS

ulTaskNotifyTake()

任务可以使用 ulTaskNotifyTake()​ 来选择性地阻塞,等待通知值变为非零,在任务的通知值不为零时返回

在退出时可以选择将通知值清零(此时通知值类似于二值信号量)或将通知值递减(此时通知值更像计数信号量)

#include "FreeRTOS.h"
#include "task.h"uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );

参数

xClearCountOnExit

  • pdFALSE

    • 每次成功调用后通知值减 1,类似计数信号量的效果
  • pdTRUE

    • 每次成功调用后通知值重置为 0,类似二值信号量的效果

xTicksToWait​等待通知的最大时间

返回值

任务的通知值在被递减或清除之前的值

Example Code:Simple Task Notification in FreeRTOS
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"TaskHandle_t task0Handle = NULL;
TaskHandle_t task1Handle = NULL;void Task0(void *pvParam)
{printf("Task0 is running\n");while (true){printf("Task0 is waitting for notification\n");ulTaskNotifyTake(pdTRUE, portMAX_DELAY);printf("Task0 got notification\n"); // Task0 等待 Task1 的通知vTaskDelay(pdMS_TO_TICKS(1000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");vTaskDelay(pdMS_TO_TICKS(5000));while (true){printf("Task1 is sending notification\n");xTaskNotifyGive(task0Handle); // Task1 通知 Task0vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, &task0Handle, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, &task1Handle, 0);xTaskResumeAll();
}

Notification Value

xTaskNotify()

用于直接向任务发送事件并解除阻塞,并可选地以以下方式之一更新接收任务的通知值

  • 将一个 32 位的数字写入通知值
  • 增加一个(增量)通知值
  • 设置一个或多个通知值
  • 保持通知值不变
#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );

参数

xTaskToNotify​被通知的 Task 句柄

ulValue​用于更新被通知任务的通知值,如何解释 ulValue 取决于 eAction 参数的值

eAction

  • eNoAction​任务被通知,但通知值不变
  • eSetBits​任务的通知值与 ulValue 进行按位或(or) 操作
  • eIncrement​任务的通知值加 1
  • eSetValueWithOverwrite​任务的通知值被无条件设置为 ulValue,即使之前已经有通知
  • eSetValueWithoutOverwrite​如果任务已经有通知待处理,则通知值不会被改变xTaskNotify()​ 将返回 pdFAIL​;如果任务没有待处理的通知,则其通知值会被设置为 ulValue

返回值

在除eSetValueWithoutOverwrite​所有其他情况下,返回 pdPASS

xTaskNotifyWait()

如果接收任务已经被阻塞并等待通知,当一个通知到达时,接收任务将从阻塞状态移除并清除通知

#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );

参数

ulBitsToClearOnEntry

  • 在调用 xTaskNotifyWait()​ 时,通知值中的某些位会在函数进入时被清除
  • 如果 ulBitsToClearOnEntry​ 设置为 0x01,则任务通知值中的第 0 位会在函数进入时被清除
  • 如果设置为 0xffffffff​(ULONG_MAX​),则通知值的所有位都会被清除,相当于将通知值重置为 0
  • 注意:仅当调用时没有挂起的通知时,清除操作才会执行

ulBitsToClearOnExit

  • 在接收到通知后,在函数退出前通知值中的某些位会被清除
  • 如果设置为 0xffffffff​(ULONG_MAX​),则通知值的所有位都会被清除

pulNotificationValue

  • 用于将任务的通知值传递给调用者
  • 保存的是 在清除ulBitsToClearOnExit的位之前的通知值
  • 如果不需要获取通知值,可以将其设置为 NULL

xTicksToWait​最大等待时间

返回值

  • pdTRUE​接收到了通知,或在调用时通知已挂起
  • pdFALSE​在等待超时时间内没有接收到通知

Example Code:Task Notification with Conditional Actions Based on Values
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"TaskHandle_t task0Handle = NULL;
TaskHandle_t task1Handle = NULL;void Task0(void *pvParam)
{printf("Task0 is running\n");uint32_t notifiedValue = 0;while (true){xTaskNotifyWait(0x00, 0xffffffff, &notifiedValue, portMAX_DELAY);if (notifiedValue == 0x00000001) // 当接收到的通知值为 0x01 时,执行相应操作{printf("Task0 get notification: bit_0\n");}else if (notifiedValue == 0x00000002){printf("Task0 get notification: bit_1\n");}else if (notifiedValue == 0x00000004){printf("Task0 get notification: bit_2\n");}else{printf("Task0 get notification: unknown\n");}vTaskDelay(pdMS_TO_TICKS(3000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");vTaskDelay(5000 / portTICK_PERIOD_MS);while (true){printf("Task1 is sending notification\n");xTaskNotify(task0Handle, 0x01, eSetValueWithOverwrite); // 发送 bit_0,覆盖之前的值vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x02, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x03, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x04, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);}
}void app_main(void)
{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, &task0Handle, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, &task1Handle, 0);xTaskResumeAll();
}

相关文章:

ESP32学习笔记_FreeRTOS(6)——Event and Notification

摘要(From AI): 这篇博客详细介绍了 FreeRTOS 中的事件组和任务通知机制&#xff0c;讲解了事件组如何通过位操作实现任务间的同步与通信&#xff0c;以及任务如何通过通知机制进行阻塞解除和数据传递。博客提供了多个代码示例&#xff0c;展示了如何使用事件组和任务通知在多任…...

力扣-数组-350 两个数组的交集Ⅱ

解析 与刚刚的《两个数组的交集》一样&#xff0c;只是这道题允许重复&#xff0c;将上一题的set去除即可。 代码 class Solution { public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {vector<int> res;int index1 …...

云原生第二次练习

1.判断192.168.1.0/24网络中&#xff0c;当前在线的ip有哪些&#xff0c;并编写脚本打印出来。 #!/bin/bash for ip in $(seq 1 254); doping -c 1 -W 1 "192.168.1.$ip" > /dev/null 2>&1if [ $? -eq 0 ]; thenecho "192.168.1.$ip is online&qu…...

SpringMVC复习笔记

文章目录 SpringMVC 概念和基本使用SpringMVC 简介SpringMVC 核心组件和调用流程SpringMVC 基本使用第一步&#xff1a;导入依赖第二步&#xff1a;Controller 层开发第三步&#xff1a;SpringMVC 配置类配置核心组件第四步&#xff1a;SpringMVC 环境搭建第五步&#xff1a;部…...

前端小案例——网页井字棋

前言&#xff1a;我们在学习完了HTML、CSS和JavaScript之后&#xff0c;就会想着使用这三个东西去做一些小案例&#xff0c;不过又没有什么好的案例让我们去练手&#xff0c;本篇文章就提供里一个案例——网页井字棋。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可…...

ComfyUI-PromptOptimizer:文生图提示优化节点

ComfyUI-PromptOptimizer 是 ComfyUI 的一个自定义节点&#xff0c;旨在优化文本转图像模型的提示。它将用户输入的提示转换为更详细、更多样化、更生动的描述&#xff0c;使其更适合生成高质量的图像。无需本地模型。 1、功能 提示优化&#xff1a;优化用户输入的提示以生成…...

AudioGPT全新的 音频内容理解与生成系统

AudioGPT全新的 音频内容理解与生成系统 ChatGPT、GPT-4等大型语言模型 (LLM) 在语言理解、生成、交互和推理方面表现出的非凡能力,引起了学界和业界的极大关注,也让人们看到了LLM在构建通用人工智能 (AGI) 系统方面的潜力。 现有的GPT模型具有极高的语言生成能力,是目前最…...

thinkphp6 + redis实现大数据导出excel超时或内存溢出问题解决方案

redis下载安装&#xff08;window版本&#xff09; 参考地址&#xff1a;https://blog.csdn.net/Ci1693840306/article/details/144214215 php安装redis扩展 参考链接&#xff1a;https://blog.csdn.net/jianchenn/article/details/106144313 解决思路&#xff1a;&#xff0…...

Hexo + NexT + Github搭建个人博客

文章目录 一、 安装二、配置相关项NexT config更新主题主题样式本地实时预览常用命令 三、主题设置1.侧边栏2.页脚3.帖子发布字数统计 4.自定义自定义页面Hexo 的默认页面自定义 404 页自定义样式 5.杂项搜索服务 四、第三方插件NexT 自带插件评论系统阅读和访问人数统计 五、部…...

使用Sum计算Loss和解决梯度累积(Gradient Accumulation)的Bug

使用Sum计算Loss和解决梯度累积的Bug 学习 https://unsloth.ai/blog/gradient&#xff1a;Bugs in LLM Training - Gradient Accumulation Fix 这篇文章的记录。 在深度学习训练过程中&#xff0c;尤其是在大批量&#xff08;large batch&#xff09;训练中&#xff0c;如何高…...

基于本地消息表实现分布式事务

假设我们有一个电商系统,包含订单服务和库存服务。当用户下单时,需要在订单服务中创建订单,同时在库存服务中扣减库存。这是一个典型的分布式事务场景,我们需要保证这两个操作要么都成功,要么都失败,以保证数据的最终一致性。 项目结构: 订单服务(Order Service)库存服务(Inv…...

Web3与加密技术的结合:增强个人隐私保护的未来趋势

随着互联网的快速发展&#xff0c;个人隐私和数据安全问题越来越受到关注。Web3作为新一代互联网架构&#xff0c;凭借其去中心化的特性&#xff0c;为个人隐私保护提供了全新的解决方案。而加密技术则是Web3的重要组成部分&#xff0c;进一步增强了隐私保护的能力。本文将探讨…...

广播网络实验

1 实验内容 1、构建星性拓扑下的广播网络,实现hub各端口的数据广播,验证网络的连通性并测试网络效率 2、构建环形拓扑网络,验证该拓扑下结点广播会产生数据包环路 2 实验流程与结果分析 2.1 实验环境 ubuntu、mininet、xterm、wireshark、iperf 2.2 实验方案与结果分析…...

Vscode——SSH连接不上的一种解决办法

一、完整报错: > @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ > IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! > Someone could be eavesdropping on you right now (man-in-the...

ChatGPT大模型极简应用开发-目录

引言 要理解 ChatGPT&#xff0c;了解其背后的 Transformer 架构和 GPT 技术一路的演进则变得非常必要。 ChatGPT 背后的 LLM 技术使普通人能够通过自然语言完成过去只能由程序员通过编程语言实现的任务&#xff0c;这是一场巨大的变革。然而&#xff0c;人类通常容易高估技术…...

EI Scopus双检索 | 2025年第四届信息与通信工程国际会议(JCICE 2025)

会议简介 Brief Introduction 2025年第四届信息与通信工程国际会议(JCICE 2025) 会议时间&#xff1a;2025年7月25日-27日 召开地点&#xff1a;中国哈尔滨 大会官网&#xff1a;www.jcice.org 由黑龙江大学和成都信息工程大学主办&#xff0c;江苏科技大学协办的2025年第四届信…...

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式 3.1 注解方式 基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听重试过程 监…...

TiDB 和 MySQL 的关系:这两者到底有什么不同和联系?

TiDB 和 MySQL 的关系&#xff1a;这两者到底有什么不同和联系&#xff1f; 在了解 TiDB 和 MySQL 之间的关系时&#xff0c;很多人可能会有疑问&#xff1a;这两个数据库到底有什么区别和联系&#xff1f;是不是 TiDB 就是 MySQL 的升级版&#xff1f;或者 TiDB 是一种“替代…...

【Java】JDK17的下载安装(与JDK1.8相互切换)

本文以参考以下链接为主&#xff1a;JDK17 如果上述操作不生效&#xff0c;请看以下操作&#xff1a; 添加以下变量并移动到最上面即可...

CSS3 3D 转换介绍

CSS3 中的 3D 转换提供了一种在二维屏幕上呈现三维效果的方式&#xff0c;主要包括translate3d、rotate3d、scale3d等转换函数&#xff0c;下面来详细介绍&#xff1a; 1. 3D 转换的基本概念 坐标系 在 CSS3 的 3D 空间中&#xff0c;使用的是右手坐标系。X 轴是水平方向&…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...