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

【FreeRTOS】同步互斥与通信 有缺陷的同步示例

目录

  • 1 同步互斥与通信
    • 1.1 同步互斥与通信概述
    • 1.2 同步与互斥的概念
    • 1.3 同步的例子:有缺陷
    • 1.4 freertos.c源码
      • 3. 互斥的例子:有缺陷
      • 4. 通信的例子:有缺陷
      • 5. FreeRTOS的解决方案


1 同步互斥与通信

1.1 同步互斥与通信概述

参考《FreeRTOS入门与工程实践(基于DshanMCU-103)》里《第10章 同步互斥与通信》

本章是概述性的内容。可以把多任务系统当做一个团队,里面的每一个任务就相当于团队里的一个人。团队成员之间要协调工作进度(同步)、争用会议室(互斥)、沟通(通信)。多任务系统中所涉及的概念,都可以在现实生活中找到例子。

各类RTOS都会涉及这些概念:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)等。我们先站在更高角度来讲解这些概念。

1.2 同步与互斥的概念

一句话理解同步与互斥:我等你用完厕所,我再用厕所。

什么叫同步?就是:哎哎哎,我正在用厕所,你等会。 什么叫互斥?就是:哎哎哎,我正在用厕所,你不能进来。

同步与互斥经常放在一起讲,是因为它们之的关系很大,“互斥”操作可以使用“同步”来实现。我“等”你用完厕所,我再用厕所。这不就是用“同步”来实现“互斥”吗?

再举一个例子。在团队活动里,同事A先写完报表,经理B才能拿去向领导汇报。经理B必须等同事A完成报表,AB之间有依赖,B必须放慢脚步,被称为同步。在团队活动中,同事A已经使用会议室了,经理B也想使用,即使经理B是领导,他也得等着,这就叫互斥。经理B跟同事A说:你用完会议室就提醒我。这就是使用"同步"来实现"互斥"。

有时候看代码更容易理解,伪代码如下:

 void  抢厕所(void){if (有人在用) 我眯一会;用厕所;喂,醒醒,有人要用厕所吗;}

1.3 同步的例子:有缺陷

程序:在06_create_task_use_params的基础上,修改出12_task_sync_exclusion

创建两个任务:一个用来执行大量的计算任务,另一个永年执行打印函数显示OLED

xTaskCreate(                //加返回值是 判断任务有没有创建成功CalcTask,           //计算任务"Task1",            //声音任务128,                //栈大小NULL,       //传入的参数 g_Task1InfoosPriorityNormal,   //优先级默认NULL                //任务句柄 无);
xTaskCreate(                //加返回值是 判断任务有没有创建成功LcdPrintTask,       //LCD打印任务"Task1",            //声音任务128,                //栈大小&g_Task2Info,       //传入的参数 g_Task1InfoosPriorityNormal,   //优先级默认NULL                //任务句柄 无);

编写这两个函数

static struct TaskPrintInfo g_Task1Info = {0, 0, "Task1"};  // (0,0),Task1
static struct TaskPrintInfo g_Task2Info = {0, 3, "Task2"};  // (0,3),Task2
static struct TaskPrintInfo g_Task3Info = {0, 6, "Task3"};  // (0,6),Task3static int g_LCDCanUse = 1; //默认=1 能使用LCD
uint32_t g_sum = 0;   //定义一个计数值
static volatile int g_calc_end = 0; // 计算结束标志位,使用volatile不要用编译器优化优化uint64_t g_time = 0;void CalcTask(void *params)
{uint32_t i = 0;     //定义一个计数值g_time = system_get_ns();   //获取当前系统时间for (i = 0; i < 10000000; i ++){g_sum += i;}g_calc_end = 1; //计算完成标志位   置位g_time = system_get_ns() - g_time;  //运行这段任务消耗的时间vTaskDelete(NULL);  //计算完成杀死任务
}void LcdPrintTask(void *params)
{int len;while (1){LCD_PrintString(0, 0, "Waiting");// vTaskDelay(3000);while (g_calc_end == 0);    //等待/* 打印信息 */if (g_LCDCanUse){g_LCDCanUse = 0;LCD_ClearLine(0, 0);len = LCD_PrintString(0, 0, "Sum: ");LCD_PrintHex(len, 0, g_sum, 1);LCD_ClearLine(0, 2);len = LCD_PrintString(0, 2, "Time(ms): ");LCD_PrintSignedVal(len, 2, g_time/1000000); //打印消耗了多长时间g_LCDCanUse = 1;}vTaskDelete(NULL);  //任务自杀}
}

这里遇到了bug!!!

在这里插入图片描述

  • 程序卡死在while循环里了,但是这个变量已经是1了,为什么程序会卡死在上面两行汇编语句呢???

  • 原因是编译器优化了我们的变量

对这个变量,执行while (g_calc_end == 0); 这条语句的时候,它会读取内存,把变量的值放到CPU某个寄存器里,以后一直就判断那个寄存器,但是这个寄存器得到的是原始的值,并没有每次都去读取内存

  • 这个变量是在其他任务里被修改的,那我们使用这个变量的时候,每次都需要读内存!
  • 那怎么办呢??我们加上一个volatile就可以了

烧录代码运行
在这里插入图片描述

计算10000000个数需要2.5S,真的是这样的吗???

我们现在有两个任务

在这里插入图片描述
他们是怎么调度的呢?
两个任务优先级相同,A任务运行1ms,B任务运行1ms,A任务运行1ms,B任务运行1ms

在这里插入图片描述

任务B执行的程序是死等,这也耗费了一半的时间,在任务B的开始就等待3S左右

vTaskDelay(3000);   //开始的时候我先等待3000Tick

加上这句等待3S之后,就变成了1278ms

在这里插入图片描述

确实如此

这个死循环可以用其他方法来代替

  • 等任务A计算完成之后,用任务A唤醒任务B
  • 使用同步的时候,我们需要考虑如何提高处理器的性能!
  • 让等待的任务阻塞,不参与CPU的调度!

这节课学习了同步的例子,有缺陷的例子

学习视频:【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS(FreeRTOS教程 基于STM32,以实际项目为导向)】 【精准空降到 13:38】 https://www.bilibili.com/video/BV1Jw411i7Fz/?p=25&share_source=copy_web&vd_source=8af85e60c2df9af1f0fd23935753a933&t=818

1.4 freertos.c源码

/* USER CODE BEGIN Header */
#include "driver_led.h"
#include "driver_lcd.h"
#include "driver_mpu6050.h"
#include "driver_timer.h"
#include "driver_ds18b20.h"
#include "driver_dht11.h"
#include "driver_active_buzzer.h"
#include "driver_passive_buzzer.h"
#include "driver_color_led.h"
#include "driver_ir_receiver.h"
#include "driver_ir_sender.h"
#include "driver_light_sensor.h"
#include "driver_ir_obstacle.h"
#include "driver_ultrasonic_sr04.h"
#include "driver_spiflash_w25q64.h"
#include "driver_rotary_encoder.h"
#include "driver_motor.h"
#include "driver_key.h"
#include "driver_uart.h"
#include "music.h"/********************************************************************************* File Name          : freertos.c* Description        : Code for freertos applications******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */BaseType_t ret; // long
static TaskHandle_t xSoundTaskHandle;           // void *  在全局变量里记录句柄static StackType_t g_pucStackOfLightTask[128];  // 变量前缀的意思是 全局变量g 指针p uint8_t类型uc的StackOfLightTask 光任务的栈
StaticTask_t g_TCBofLightTask;                  // 光任务的TCB
static TaskHandle_t xLightTaskHandle;           // void *  在全局变量里记录句柄static StackType_t g_pucStackOfColorTask[128];  // 变量前缀的意思是 全局变量g 指针p uint8_t类型uc的StackOfLightTask 色任务的栈
StaticTask_t g_TCBofColorTask;                  // 色任务的TCB
static TaskHandle_t xColorTaskHandle;           // void *  在全局变量里记录句柄/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {.name = "defaultTask",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */struct TaskPrintInfo{uint8_t x;      //定义坐标xuint8_t y;      //定义坐标ychar name[16];  //定义要打印输出的内容,最多显示16个字符
};static struct TaskPrintInfo g_Task1Info = {0, 0, "Task1"};  // (0,0),Task1
static struct TaskPrintInfo g_Task2Info = {0, 3, "Task2"};  // (0,3),Task2
static struct TaskPrintInfo g_Task3Info = {0, 6, "Task3"};  // (0,6),Task3static int g_LCDCanUse = 1; //默认=1 能使用LCD
uint32_t g_sum = 0;   //定义一个计数值
static volatile int g_calc_end = 0; // 计算结束标志位,使用volatile不要用编译器优化优化uint64_t g_time = 0;void CalcTask(void *params)
{uint32_t i = 0;     //定义一个计数值g_time = system_get_ns();   //获取当前系统时间for (i = 0; i < 10000000; i ++){g_sum += i;}g_calc_end = 1; //计算完成标志位   置位g_time = system_get_ns() - g_time;  //运行这段任务消耗的时间vTaskDelete(NULL);  //计算完成杀死任务
}void LcdPrintTask(void *params)
{int len;while (1){LCD_PrintString(0, 0, "Waiting");vTaskDelay(3000);   //开始的时候我先等待3000Tickwhile (g_calc_end == 0);    //等待/* 打印信息 */if (g_LCDCanUse){g_LCDCanUse = 0;LCD_ClearLine(0, 0);len = LCD_PrintString(0, 0, "Sum: ");LCD_PrintHex(len, 0, g_sum, 1);LCD_ClearLine(0, 2);len = LCD_PrintString(0, 2, "Time(ms): ");LCD_PrintSignedVal(len, 2, g_time/1000000); //打印消耗了多长时间g_LCDCanUse = 1;}vTaskDelete(NULL);  //任务自杀}
}
/* USER CODE END FunctionPrototypes */void StartDefaultTask(void *argument);void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) *//*** @brief  FreeRTOS initialization* @param  None* @retval None*/
void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init */LCD_Init();LCD_Clear();/* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* creation of defaultTask *///  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *///  /* 创建任务:声 */
//  // 先创建一个动态分配内存的任务
//  ret = xTaskCreate(                //加返回值是 判断任务有没有创建成功
//            PlayMusic,          //孤勇者的函数
//            "SoundTask",        //声音任务
//            128,                //栈大小
//            NULL,               //无传入的参数
//            osPriorityNormal,   //优先级默认
//            & xSoundTaskHandle  //任务句柄
//            );//  
//  /* 创建任务:光 */ 
//  // 创建一个静态分配内存的任务
//  xLightTaskHandle = xTaskCreateStatic(
//            Led_Test,           //LED测试函数,PC13以500ms间隔亮灭一次
//            "LightTask",        //光任务
//            128,                //栈大小,这里提供了栈的大小(长度)
//            NULL,               //无传入的参数
//            osPriorityNormal,   //优先级默认
//            g_pucStackOfLightTask,  // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小,最开始栈的类型不对,栈的类型uint32_t
//            &g_TCBofLightTask       // 取址TCB
//  );
//  
//  /* 创建任务:色 */ 
//  xColorTaskHandle = xTaskCreateStatic(
//            ColorLED_Test,           //LED测试函数,PC13以500ms间隔亮灭一次
//            "ColorTask",        //光任务
//            128,                //栈大小,这里提供了栈的大小(长度)
//            NULL,               //无传入的参数
//            osPriorityNormal,   //优先级默认
//            g_pucStackOfColorTask,  // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小
//            &g_TCBofColorTask       // 取址TCB
//  );xTaskCreate(                //加返回值是 判断任务有没有创建成功CalcTask,           //计算任务"Task1",            //声音任务128,                //栈大小NULL,       //传入的参数 g_Task1InfoosPriorityNormal,   //优先级默认NULL                //任务句柄 无);xTaskCreate(                //加返回值是 判断任务有没有创建成功LcdPrintTask,       //LCD打印任务"Task1",            //声音任务128,                //栈大小&g_Task2Info,       //传入的参数 g_Task1InfoosPriorityNormal,   //优先级默认NULL                //任务句柄 无);/* USER CODE END RTOS_THREADS *//* USER CODE BEGIN RTOS_EVENTS *//* add events, ... *//* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask *//*** @brief  Function implementing the defaultTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */LCD_Init();LCD_Clear();for(;;){//Led_Test();//LCD_Test();//MPU6050_Test(); //DS18B20_Test();//DHT11_Test();//ActiveBuzzer_Test();//PassiveBuzzer_Test();//ColorLED_Test();IRReceiver_Test();  //影//IRSender_Test();//LightSensor_Test();//IRObstacle_Test();//SR04_Test();//W25Q64_Test();//RotaryEncoder_Test();//Motor_Test();//Key_Test();//UART_Test();}/* USER CODE END StartDefaultTask */
}/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application *//* USER CODE END Application */

在这里插入图片描述

3. 互斥的例子:有缺陷

讲解这个程序"06_create_task_use_params"的互斥缺陷。

4. 通信的例子:有缺陷

5. FreeRTOS的解决方案

  • 正确性

  • 效率:等待者要进入阻塞状态

  • 多种解决方案

相关文章:

【FreeRTOS】同步互斥与通信 有缺陷的同步示例

目录 1 同步互斥与通信1.1 同步互斥与通信概述1.2 同步与互斥的概念1.3 同步的例子&#xff1a;有缺陷1.4 freertos.c源码3. 互斥的例子&#xff1a;有缺陷4. 通信的例子&#xff1a;有缺陷5. FreeRTOS的解决方案 1 同步互斥与通信 1.1 同步互斥与通信概述 参考《FreeRTOS入门…...

Lambda表达式讲解

简介: Lambda表达式的使用场景非常广泛,主要包括函数式编程、集合操作、排序、线程编程、GUI事件处理、数据处理、Web开发等。 函数式编程:Lambda表达式是函数式编程的重要特性,可以用于替代传统的匿名内部类,简化代码,提高可读性。 集合操作:Lambda表达式可以与集合…...

深入了解Linux中的dnsmasq:配置与优化指南

目录 安装dnsmasqUbuntu/DebianCentOS/RHELFedora 配置dnsmasq基本配置高级配置 启动和测试dnsmasq优化dnsmasq性能优化安全性优化 常见问题与故障排除无法解析域名DHCP分配失败 在Linux系统中&#xff0c; dnsmasq 是一个轻量级的网络服务&#xff0c;主要用于提供DNS缓存和D…...

【React】Ant Design -- Table分页功能实现

实现步骤 为Table组件指定pagination属性来展示分页效果在分页切换事件中获取到筛选表单中选中的数据使用当前页数据修改params参数依赖引起接口重新调用获取最新数据 const pageChange (page) > {// 拿到当前页参数 修改params 引起接口更新setParams({...params,page})…...

400G SR4和800G SR8光模块在AI集群中的应用

人工智能&#xff08;AI&#xff09;技术的快速发展下&#xff0c;AI集群的计算能力和数据传输需求不断提升。为了满足这一需求&#xff0c;光模块技术也在不断进步。高速率光模块作为新一代高速光通信解决方案&#xff0c;正在逐步应用于AI集群中&#xff0c;为其提供更高效、…...

ARM功耗管理软件之DVFSAVS

安全之安全(security)博客目录导读 思考&#xff1a;功耗管理软件栈及示例&#xff1f;WFI&WFE&#xff1f;时钟&电源树&#xff1f;DVFS&AVS&#xff1f; 目录 一、ARM功耗管理软件之DVFS 二、ARM功耗管理软件之AVS 一、ARM功耗管理软件之DVFS 有一个实现特定…...

【堆 优先队列】23. 合并 K 个升序链表

本文涉及知识点 堆 优先队列 LeetCode23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#…...

云桌面运维工程师

一 深信服驻场工程师 1 深信服AC、AF、AD、NGAF、WOC Atrust、WAF项目实施经验者优先考虑。 负责云桌面POC测试 部署和配置&#xff1a;设置云桌面基础设施&#xff0c;包括虚拟化平台、云桌面管理软件和相关组件。确保正确配置网络、存储和安全设置。 用户体验&#xff1…...

AGI 之 【Hugging Face】 的【Transformer】的 [ Transformer 架构 ] / [ 编码器 ]的简单整理

AGI 之 【Hugging Face】 的【Transformer】的 [ Transformer 架构 ] / [ 编码器 ]的简单整理 目录 AGI 之 【Hugging Face】 的【Transformer】的 [ Transformer 架构 ] / [ 编码器 ]的简单整理 一、简单介绍 二、Transformer 三、Transformer架构 四、编码器 1、自注意…...

【在大模型RAG系统中应用知识图谱】

【引子】 关于大模型及其应用方面的文章层出不穷&#xff0c;聚焦于自己面对的问题&#xff0c;有针对性的阅读会有很多的启发&#xff0c;本文源自Whyhow.ai 上的一些文字和示例。对于在大模型应用过程中如何使用知识图谱比较有参考价值&#xff0c;特汇总分享给大家。 在基于…...

第二十条:与抽象类相比,优先选择接口

要定义多种实现的类型&#xff1a;JAVA有两种机制&#xff1a;接口和抽象类。这两种机制都支持为某些实例方法提供实现&#xff0c;但二者有个重要的区别&#xff1a;要实现由抽象类定义的类型&#xff0c;这个类必须是抽象类的子类。因为Java只允许单继承&#xff0c;对抽象类…...

20240705

Nacos Service Discovery 通过nacos实现的服务发现平台 Spring Cloud Alibaba Sentinel 提供 Sentinel 自动接入和配置支持&#xff0c;提供 Spring Web/WebFlux、Feign、RestTemplate、注解等适配 Spring Cloud Alibaba Sentinel DataSource 提供 Sentinel 动态数据源接入支…...

【2023ICPC网络赛I 】E. Magical Pair

当时在做洛谷U389682 最大公约数合并的时候我就想到把每个质因子分解出来然后跑高维前缀和&#xff0c;但是那一道题不是用这个方法&#xff0c;所有我也一直在思考这种做法是不是真的有用。因为昨天通过2024上海大学生程序设计竞赛I-六元组计数这道题我了解到了不少关于原根的…...

Kafka-服务端-网络层-源码流程

整体架构如下所示&#xff1a; responseQueue不在RequestChannel中&#xff0c;在Processor中&#xff0c;每个Processor内部有一个responseQueue 客户端发送的请求被Acceptor转发给Processor处理处理器将请求放到RequestChannel的requestQueue中KafkaRequestHandler取出reque…...

百日筑基第十一天-看看SpringBoot

百日筑基第十一天-看看SpringBoot 创建项目 Spring 官方提供了 Spring Initializr 的方式来创建 Spring Boot 项目。网址如下&#xff1a; https://start.spring.io/ 打开后的界面如下&#xff1a; 可以将 Spring Initializr 看作是 Spring Boot 项目的初始化向导&#xff…...

Generative Modeling by Estimating Gradients of the Data Distribution

Generative Modeling by Estimating Gradients of the Data Distribution 本文介绍宋飏提出的带噪声扰动的基于得分的生成模型。首先介绍基本的基于得分的生成模型的训练方法&#xff08;得分匹配&#xff09;和采样方法&#xff08;朗之万动力学&#xff09;。然后基于流形假…...

vector与list的简单介绍

1. 标准库中的vector类的介绍&#xff1a; vector是表示大小可以变化的数组的序列容器。 就像数组一样&#xff0c;vector对其元素使用连续的存储位置&#xff0c;这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素&#xff0c;并且与数组中的元素一样高效。但与数…...

四种线程池的使用,优缺点分析

池化思想&#xff1a;线程池、字符串常量池、数据库连接池 提高资源的利用率 下面是手动创建线程和执行任务过程&#xff0c;可见挺麻烦的&#xff0c;而且线程利用率不高。 手动创建线程对象执行任务执行完毕&#xff0c;释放线程对象 线程池的优点&#xff1a; 提高线程的…...

什么是 BEM 规范

BEM&#xff08;Block, Element, Modifier&#xff09;是一种 CSS 命名规范&#xff0c;旨在提高代码的可读性和可维护性。BEM 规范通过明确的命名规则来定义组件和组件的各个部分&#xff0c;使开发者能够更容易地理解和维护代码。 BEM 命名规范的基本概念 Block&#xff08…...

【Node.JS】入门

文章目录 Node.js的入门涉及对其基本概念、特点、安装、以及基本使用方法的了解。以下是对Node.js入门的详细介绍&#xff1a; 一、Node.js基本概念和特点 定义&#xff1a;Node.js是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;它使得JavaScript能够运行在服务器…...

提升90%效率:OpenCore EFI自动化配置工具OpCore-Simplify实战指南

提升90%效率&#xff1a;OpenCore EFI自动化配置工具OpCore-Simplify实战指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 副标题&#xff1a;面向…...

Leather Dress Collection 模型Java后端集成指南:SpringBoot微服务开发

Leather Dress Collection 模型Java后端集成指南&#xff1a;SpringBoot微服务开发 最近在做一个电商相关的项目&#xff0c;需要集成一个能生成皮革服饰设计图的AI模型&#xff0c;正好接触到了Leather Dress Collection。作为后端开发&#xff0c;我的第一反应就是&#xff…...

SiameseAOE中文-base惊艳效果:结构化输出JSON兼容下游BI/报表系统直连

SiameseAOE中文-base惊艳效果&#xff1a;结构化输出JSON兼容下游BI/报表系统直连 1. 模型效果惊艳展示 SiameseAOE通用属性观点抽取模型在中文文本处理方面表现出色&#xff0c;能够从非结构化文本中精准提取结构化信息。最令人印象深刻的是&#xff0c;模型输出的JSON格式数…...

【全场景优化】WaveTools鸣潮性能调校指南:从卡顿到流畅的完整解决方案

【全场景优化】WaveTools鸣潮性能调校指南&#xff1a;从卡顿到流畅的完整解决方案 【免费下载链接】WaveTools &#x1f9f0;鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 问题定位&#xff1a;硬件与软件的兼容性挑战 当代游戏性能优化面临的核…...

DAMOYOLO-S基础教程:理解count字段与实际业务中目标计数逻辑映射

DAMOYOLO-S基础教程&#xff1a;理解count字段与实际业务中目标计数逻辑映射 1. 从一次“数数”的困惑说起 前两天&#xff0c;一个做零售分析的朋友找我帮忙。他兴奋地告诉我&#xff0c;他们用上了最新的AI目标检测模型&#xff0c;想自动统计货架上的商品数量。他上传了一…...

Windows/Linux双平台实战:用Docker快速部署MySQL 5.7.36并导入数据

跨平台Docker实战&#xff1a;MySQL 5.7.36高效部署与数据迁移指南 在混合开发环境中&#xff0c;数据库的快速部署与迁移往往是影响团队协作效率的关键因素。想象一下这样的场景&#xff1a;一位开发者刚在Windows笔记本上完成本地测试&#xff0c;需要将包含复杂表结构的MySQ…...

终极指南:使用Refine和Ant Design快速构建专业列表页面

终极指南&#xff1a;使用Refine和Ant Design快速构建专业列表页面 【免费下载链接】refine 一个用于构建内部工具、管理面板、仪表盘和B2B应用程序的React框架&#xff0c;具有无与伦比的灵活性。 项目地址: https://gitcode.com/GitHub_Trending/re/refine Refine是一…...

宝藏分享!实用AI写教材工具,快速产出低查重专业教材!

AI写教材工具&#xff1a;提升创作效率的利器 在撰写教材的过程中&#xff0c;总会遇到一种令人沮丧的“慢节奏”。尽管框架与资料已经准备就绪&#xff0c;内容创作却常常陷入困境&#xff1a;一句话反复推敲数十分钟&#xff0c;还是觉得表达不够完美&#xff1b;章节间的衔…...

5个高效能的LabelImg图像标注效率提升实践

5个高效能的LabelImg图像标注效率提升实践 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out Label Studio, the open s…...

DeepSeek API实战:如何用Python脚本绕过Postman直接调用(附完整代码)

DeepSeek API高效调用指南&#xff1a;Python脚本开发实战 在当今快节奏的开发环境中&#xff0c;效率是衡量开发者生产力的关键指标。传统API测试工具如Postman虽然功能强大&#xff0c;但在自动化流程和持续集成场景中往往显得笨重。本文将带你探索一种更轻量、更灵活的解决方…...