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

FreeRTOS 空闲任务

文章目录

  • 一、空闲任务详解
    • 1. 空闲任务简介
    • 2. 空闲任务的创建
    • 3. 空闲任务函数
  • 二、空闲任务钩子函数详解
    • 1. 钩子函数
    • 2. 空闲任务钩子函数
  • 三、空闲任务钩子函数实验


一、空闲任务详解

1. 空闲任务简介

当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务,这样就可以确保至少有一任务可以运行。但是这个空闲任务使用最低优先级,如果应用中有其他高优先级任务处于就绪态的话这个空闲任务就不会跟高优先级的任务抢占 CPU 资源。空闲任务还有另外一个重要的职责,如果某个任务要调用函数 vTaskDelete()删除自身,那么这个任务的任务控制块 TCB 和任务堆栈等这些由 FreeRTOS 系统自动分配的内存需要在空闲任务中释放掉,如果删除的是别的任务那么相应的内存就会被直接释放掉,不需要在空闲任务中释放。因此,一定要给空闲任务执行的机会!除此以外空闲任务就没有什么特别重要的功能了,所以可以根据实际情况减少空闲任务使用 CPU 的时间(比如,当 CPU 运行空闲任务的时候使处理器进入低功耗模式)。

用户可以创建与空闲任务优先级相同的应用任务,当宏 configIDLE_SHOULD_YIELD 为 1的话应用任务就可以使用空闲任务的时间片,也就是说空闲任务会让出时间片给同优先级的应用任务。这种方法在 介绍configIDLE_SHOULD_YIELD 的时候就讲过了,这种机制要求FreeRTOS 使用抢占式内核。

2. 空闲任务的创建

当调用函数 vTaskStartScheduler()启动任务调度器的时候此函数就会自动创建空闲任务,代码如下:

void vTaskStartScheduler( void )
{BaseType_t xReturn;//创建空闲任务,使用最低优先级#if( configSUPPORT_STATIC_ALLOCATION == 1 ) (1){StaticTask_t *pxIdleTaskTCBBuffer = NULL;StackType_t *pxIdleTaskStackBuffer = NULL;uint32_t ulIdleTaskStackSize;vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, \&ulIdleTaskStackSize );xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,"IDLE",ulIdleTaskStackSize,( void * ) NULL,( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),pxIdleTaskStackBuffer,pxIdleTaskTCBBuffer ); if( xIdleTaskHandle != NULL ){xReturn = pdPASS;}else{xReturn = pdFAIL;}}#else (2){xReturn = xTaskCreate( prvIdleTask,"IDLE", configMINIMAL_STACK_SIZE,( void * ) NULL,( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),&xIdleTaskHandle );}#endif /* configSUPPORT_STATIC_ALLOCATION *//*********************************************************************//**************************省略其他代码*******************************//*********************************************************************/
}

(1)、使用静态方法创建空闲任务。
(2)、使用动态方法创建空闲任务,空闲任务的任务函数为 prvIdleTask(),任务堆栈大小为configMINIMAL_STACK_SIZE,任务堆栈大小可以在 FreeRTOSConfig.h 中修改。任务优先级为tskIDLE_PRIORITY,宏 tskIDLE_PRIORITY 为 0,说明空闲任务优先级最低,用户不能随意修改空闲任务的优先级!

3. 空闲任务函数

空闲任务的任务函数为 prvIdleTask(),但是实际上是找不到这个函数的,因为它是通过宏定义来实现的,在文件 portmacro.h 中有如下宏定义:

#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )

其中 portTASK_FUNCTION()在文件 tasks.c 中有定义,它就是空闲任务的任务函数,源码如下:

static portTASK_FUNCTION( prvIdleTask, pvParameters ) (1)
{( void ) pvParameters; //防止报错//本函数为 FreeRTOS 的空闲任务任务函数,当任务调度器启动以后空闲任务会自动//创建for( ;; ){//检查是否有任务要删除自己,如果有的话就释放这些任务的任务控制块 TCB 和//任务堆栈的内存prvCheckTasksWaitingTermination(); (2)#if ( configUSE_PREEMPTION == 0 ){//如果没有使用抢占式内核的话就强制进行一次任务切换查看是否有其他//任务有效,如果有使用抢占式内核的话就不需要这一步,因为只要有任//何任务有效(就绪)之后都会自动的抢夺 CPU 使用权taskYIELD();}#endif /* configUSE_PREEMPTION */#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) (3){//如果使用抢占式内核并且使能时间片调度的话,当有任务和空闲任务共享//一个优先级的时候,并且此任务处于就绪态的话空闲任务就应该放弃本时//间片,将本时间片剩余的时间让给这个就绪任务。如果在空闲任务优先级//下的就绪列表中有多个用户任务的话就执行这些任务。if( listCURRENT_LIST_LENGTH( \ (4)&( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) )> ( UBaseType_t ) 1 ){taskYIELD();}else{mtCOVERAGE_TEST_MARKER();}}#endif #if ( configUSE_IDLE_HOOK == 1){extern void vApplicationIdleHook( void );//执行用户定义的空闲任务钩子函数,注意!钩子函数里面不能使用任何//可以引起阻塞空闲任务的 API 函数。vApplicationIdleHook(); (5)}#endif /* configUSE_IDLE_HOOK *///如果使能了 Tickless 模式的话就执行相关的处理代码#if ( configUSE_TICKLESS_IDLE != 0 ) (6){TickType_t xExpectedIdleTime;xExpectedIdleTime = prvGetExpectedIdleTime(); (7)if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) (8){vTaskSuspendAll(); (9){//调度器已经被挂起,重新采集一次时间值,这次的时间值可以//使用configASSERT( xNextTaskUnblockTime >= xTickCount );xExpectedIdleTime = prvGetExpectedIdleTime(); (10)if( xExpectedIdleTime >=\configEXPECTED_IDLE_TIME_BEFORE_SLEEP ){traceLOW_POWER_IDLE_BEGIN();portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); (11)traceLOW_POWER_IDLE_END();}else{mtCOVERAGE_TEST_MARKER();}}( void ) xTaskResumeAll(); (12)}else{mtCOVERAGE_TEST_MARKER();}}#endif /* configUSE_TICKLESS_IDLE */}
}

(1)、将此行展开就是 static void prvIdleTask(void *pvParameters),创建空闲任务的时候任务函数名就是 prvIdleTask()。

(2)、调用函数 prvCheckTasksWaitingTermination()检查是否有需要释放内存的被删除任务,当 有 任 务 调 用 函 数 vTaskDelete() 删 除 自 身 的 话 , 此 任 务 就 会 添 加 到 列 表xTasksWaitingTermination 中 。 函 数 prvCheckTasksWaitingTermination() 会 检 查 列 表xTasksWaitingTermination 是否为空,如果不为空的话就依次将列表中所有任务对应的内存释放掉(任务控制块 TCB 和任务堆栈的内存)。

(3)、使用抢占式内核并且 configIDLE_SHOULD_YIELD 为 1,说明空闲任务需要让出时间片给同优先级的其他就绪任务。

(4)、检查优先级为 tskIDLE_PRIORITY(空闲任务优先级)的就绪任务列表是否为空,如果不为空的话就调用函数 taskYIELD()进行一次任务切换。

(5)、如果使能了空闲任务钩子函数的话就执行这个钩子函数,空闲任务钩子函数的函数名为 vApplicationIdleHook(),这个函数需要用户自行编写!在编写这个这个钩子函数的时候一定不能调用任何可以阻塞空闲任务的 API 函数。

(6)、configUSE_TICKLESS_IDLE 不为 0,说明使能了 FreeRTOS 的低功耗 Tickless 模式。

(7)、调用函数 prvGetExpectedIdleTime()获取处理器进入低功耗模式的时长,此值保存在变量 xExpectedIdleTime 中,单位为时钟节拍数。

(8)、xExpectedIdleTime 值要大于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 才有效。

(9)、处理 Tickless 模式,挂起任务调度器,其实就是起到临界段代码保护功能

(10)、重新获取一次时间值,这次的时间值是直接用于portSUPPRESS_TICKS_AND_SLEEP()的。

(11)、调用 portSUPPRESS_TICKS_AND_SLEEP()进入低功耗 Tickless 模式。

(12)、恢复任务调度器。

二、空闲任务钩子函数详解

1. 钩子函数

FreeRTOS 中有多个钩子函数,钩子函数类似回调函数,当某个功能(函数)执行的时候就会调用钩子函数,至于钩子函数的具体内容那就由用户来编写。如果不需要使用钩子函数的话就什么也不用管,钩子函数是一个可选功能,可以通过宏定义来选择使用哪个钩子函数,可选的钩子函数如下表所示
在这里插入图片描述
钩子函数的使用方法基本相同,用户使能相应的钩子函数,然后自行根据实际需求编写钩子函数的内容,下一节我们会以空闲任务钩子函数为例讲解如何使用钩子函数。

2. 空闲任务钩子函数

在每个空闲任务运行周期都会调用空闲任务钩子函数,如果想在空闲任务优先级下处理某个任务有两种选择:
● 在空闲任务钩子函数中处理任务。
不管什么时候都要保证系统中至少有一个任务可以运行,因此绝对不能在空闲任务钩子函数中调用任何可以阻塞空闲任务的 API 函数,比如 vTaskDelay(),或者其他带有阻塞时间的信号量或队列操作函数。

● 创建一个与空闲任务优先级相同的任务。
创建一个任务是最好的解决方法,但是这种方法会消耗更多的 RAM。
要使用空闲任务钩子函数首先要在 FreeRTOSConfig.h 中将宏 configUSE_IDLE_HOOK 改为 1,然后编写空闲任务钩子函数 vApplicationIdleHook()。通常在空闲任务钩子函数中将处理器设置为低功耗模式来节省电能,为了与 FreeRTOS 自带的 Tickless 模式做区分,这里我暂且将这种低功耗的实现方法称之为通用低功耗模式(因为几乎所有的 RTOS 系统都可以使用这种方法实现低功耗)。这种通用低功耗模式和 FreeRTOS 自带的 Tickless 模式的区别我们通过下图来对比分析一下。
在这里插入图片描述
图中有三个任务,它们分别为一个空闲任务(Idle),两个用户任务(Task1 和 Task2),其中空闲任务一共有运行了三次,分别为(1)、(2)、(3),其中 T1 到 T12 是 12 个时刻,下面我们分别从这两种低功耗的实现方法去分析一下整个过程。

(1)通用低功耗模式
如果使用通用低功耗模式的话每个滴答定时器中断都会将处理器从低功耗模式中唤醒,以(1)为例,再 T2 时刻处理器从低功耗模式中唤醒,但是接下来由于没有就绪的其他任务所以处理器又再一次进入低功耗模式。T2、T3 和 T4 这三个时刻都一样,反复的进入低功耗、退出低功耗,最理想的情况应该是从 T1 时刻就进入低功耗,然后在 T5 时刻退出。

在(2)中空闲任务只工作了两个时钟节拍,但是也执行了低功耗模式的进入和退出,显然这个意义不大,因为进出低功耗也是需要时间的。

(3)中空闲任务在 T12 时刻被某个外部中断唤醒,中断的具体处理过程在任务 2(使用信号量实现中断与任务之间的同步)。

(2)低功耗 Tickless 模式
在(1)中的 T1 时刻处理器进入低功耗模式,在 T5 时刻退出低功耗模式。相比通用低功耗模式少了 3 次进出低功耗模式的操作。

在(2)中由于空闲任务只运行了两个时钟节拍,所以就没必要进入低功耗模式。说明在
Tickless 模式中只有空闲任务要运行时间的超过某个最小阈值的时候才会进入低功耗模式,此阈值通过 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 来设置,上一章已经讲过了。

(3)中的情况和通用低功耗模式一样。
可以看出相对与通用低功耗模式,FreeRTOS 自带的 Tickless 模式更加合理有效,所以如果有低功耗设计需求的话大家尽量使用 FreeRTOS 再带的 Tickless 模式。当然了,如果对于功耗要求不严格的话通用低功耗模式也可以使用,下一节将通过一个实验讲解如何在空闲任务钩子函数中实现低功耗。

三、空闲任务钩子函数实验

1、实验目的
学习如何在 FreeRTOS 空闲任务钩子函数中实现低功耗。

2、实验设计
FreeRTOS 低功耗 Tickless 模式,关闭 Tickless 模式,在空闲任务钩子函数中使用 WFI 指令是处理器进入睡眠模式。

3、实验程序与分析
● 相关宏设置

#define configUSE_TICKLESS_IDLE 0 //关闭低功耗 tickless 模式
#define configUSE_IDLE_HOOK 1 //使能空闲任务钩子函数

● 空闲任务钩子函数

//进入低功耗模式前需要处理的事情
void BeforeEnterSleep(void)
{//关闭某些低功耗模式下不使用的外设时钟,此处只是演示性代码RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,DISABLE);
}//退出低功耗模式以后需要处理的事情
void AfterExitSleep(void)
{//退出低功耗模式以后打开那些被关闭的外设时钟,此处只是演示性代码RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE); 
}//空闲任务钩子函数
void vApplicationIdleHook(void)
{__disable_irq();__dsb(portSY_FULL_READ_WRITE );__isb(portSY_FULL_READ_WRITE );BeforeEnterSleep(); //进入睡眠模式之前需要处理的事情__wfi(); //进入睡眠模式AfterExitSleep(); //退出睡眠模式之后需要处理的事情__dsb(portSY_FULL_READ_WRITE );__isb(portSY_FULL_READ_WRITE );__enable_irq();
}

空闲任务钩子函数主要目的就是调用 WFI 指令使 STM32F103 进入睡眠模式,在进入和退出低功耗模式的时候也可以做一些其他处理,比如关闭外设时钟等等,用法和 FreeRTOS 的Tickless 模式类似。

● 其他任务函数和设置
其他有关设置和任务函数的内容同“FreeRTOS 实验 18-1 FreeRTOS 低功耗 Tickless 模式实验”一样,这里就不列出来了。

相关文章:

FreeRTOS 空闲任务

文章目录 一、空闲任务详解1. 空闲任务简介2. 空闲任务的创建3. 空闲任务函数 二、空闲任务钩子函数详解1. 钩子函数2. 空闲任务钩子函数 三、空闲任务钩子函数实验 一、空闲任务详解 1. 空闲任务简介 当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务,这…...

快速生成HTML结构语法、快速生成CSS样式语法以及emmet

快速生成HTML结构语法 1、生成标签直接输入标签名按Tab键即可 比如 div 然后tab键 2、如果要生成多个相同标签,加上就可以了,比如 div3就可以快捷生成三个div 3、如果有父子级关系的标签,可以用 > 比如 ul>li 就可以了 4、如果有兄弟关…...

企业直播该如何做?硬件设备、网络环境、设备连接和观看权限等整个直播流程教程

这是一份面向直播新手的企业直播说明教程,字数较多,完整看完,可能会需要求10分钟,建议您可以【收藏】,如果本文章对您有帮助,就帮助【点个赞】吧~~~ 阿酷TONY / 2023-5-12 / 原创文章 / 长沙 / 文章…...

第4章 静态网站部署

第4章 静态网站部署 Nginx是一个HTTP的web服务器,可以将服务器上的静态文件(如HTML、图片等)通过HTTP协议返回给浏览器客户端 4.1 案例:将ace-master这个静态网站部署到Nginx服务器上 4.1.1 通过Xftp将ace-master到linux服务器…...

免费版的mp3格式转换器有哪些?这三款软件帮你实现!

在娱乐文化越来越丰富的今天,人们越来越追求音乐、视频等娱乐方式,其中音乐作为一种能够治愈心灵的艺术形式备受欢迎。但要欣赏一首美妙的音乐,就需要我们自己去制作、编辑并转换其格式,以适应各种软件如MP3、MP4等格式。 方法一…...

版本控制器git

目录 一、版本控制系统 二、工作流程和使用命令 (1)工作流程 (2)一次完整流程的相关命令 1.初始化1个空的本地仓库 2.克隆方式1个远程仓库到本地仓库 3.新文件添加到暂存区 4.查看仓库状态,显示有变更的文件 5…...

接口自动化测试 vs. UI自动化测试:为什么前者更快,更省力,更稳定?

从入门到精通!企业级接口自动化测试实战,详细教学!(自学必备视频) 目录 前言: 一、什么是接口自动化测试和 UI 自动化测试 二、为什么接口自动化测试效率比 UI 自动化测试高 1.执行速度 2.维护成本 3.…...

看Chat GPT解答《情报学基础教程》课后思考和习题

情报学基础教程课后思考题 情报学经验规律 (一)按照布拉德福定律,设布拉德福常数为5, 当核心期刊数量为20时,外围一区和外围二区期刊数量各是多少? 答: 核心期刊数和外围期刊比例关系:nc: n1: n2 = 1: a : a2 (a称为布拉德福常数) 外围一区期刊数量为20*5=100,…...

线程同步、生产者消费模型和POSIX信号量

gitee仓库: 1.阻塞队列代码:https://gitee.com/WangZihao64/linux/tree/master/BlockQueue 2.环形队列代码:https://gitee.com/WangZihao64/linux/tree/master/ringqueue 条件变量 概念 概念: 利用线程间共享的全局变量进行同…...

(六)实现好友管理:教你如何在即时通信系统中添加好友

文章目录 一、引言1.1 即时通信系统中用户增加好友功能的重要性和应用场景1.2 TCP连接传输用户增加好友请求的基本原理 二、实现用户增加好友功能2.1 实现用户好友列表的展示和管理2.1.1 使用QListWidgetItem控件展示好友列表客户端关键代码展示服务端关键代码展示 三、效果展示…...

使用循环数组和环形链表实现双端队列

本文主要介绍了两种实现双端队列的数据结构 —— 基于环形链表和循环数组。两种实现方式的基本原理和特点,以及详细的Java代码实现和分析。 引言 双端队列(Deque, Double-ended queue)是一种具有队列和栈的性质的数据结构。它允许在两端插入和删除元素&#xff0c…...

谁想和我一起做低代码平台!一个可以提升技术,让简历装x的项目

序言 正如文章标题所述,最近一段时间低代码这个概念非常的火,但其实在不了解这个东西的时候觉得它真的很炫酷,从那时就萌生了做一个低代码平台的想法。 但随着时间的变化,现在市面上低代码各个业务方向的平台都有了,可…...

知识推理——CNN模型总结(一)

记录一下我看过的利用CNN实现知识推理的论文。 最后修改时间:2023.05.12 目录 1.ConvE 1.1.解决的问题 1.2.优势 1.3.贡献与创新点 1.4.方法 1.4.1 为什么用二维卷积,而不是一维卷积? 1.4.2.ConvE具体实现 1.4.3.1-N scoring 1.5.…...

OpengES中 GLSL优化要点

本文整理一些日常积累的可以优化的方向 一.延迟vector计算 在进行float与vector计算的时候,可以先确定float再计算,不要多个float一起计算 如: highp float f0,f1;highp vec4 v0,v1;v0 (v1 * f0) * f1;优化为 highp float f0,f1;highp vec…...

项目集角色定义

一、项目集经理的角色 项目集经理是由执行组织授权、领导团队实现项目集目标的人员。项目集经理对项目集的领导、 实施和绩效负责,并负责组建一支能够实现项目集目标和预期项目集效益的项目集团队。项目集经 理的角色与项目经理的角色不同。二者之间的差异是基于项…...

Unreal Engine11:触发器和计时器的使用

写在前面 主要是介绍一下触发器和计时器的使用; 一、在Actor中使用触发器 1. 新建一个C类 创建的C类也是放在Source文件夹中的Public和Private文件夹中;选择Actor作为继承的父类;头文件包括一个触发器和两个静态网格,它们共同…...

Qt之信号槽原理

Qt之信号槽原理 一.概述 所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这…...

【MySqL】 表的创建,查看,删除

目录 一.使用Cmd命令执行操作 1.使用( mysql -uroot -p)命令进入数据库 2.创建表之前先要使用数据库 3.创建表之前要先确定表的名称,列名,以及每一列的数据类型及属性 4.创建表 注意: 5.查看所有已创建的表 6.查看单表 …...

Python 字典修改对应的键值

将 key ‘1’ 的值 ‘1’, ‘3’, ‘5’ 字符,修改为 ‘2’, ‘4’, ‘5’ 。 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单………...

【JFace】ComboViewer 设置了默认值,但没有效果

问题 在数据回显时,明明在代码中通过comboViewer.setSelection设置了默认值,但没有生效(回显),是怎么回事呢 ? 分析 如果comboViewer.setSelection(new StructuredSelection(items[1]))不起作用&#xf…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【JVM】- 内存结构

引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...