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

《FreeRTOS任务删除篇》

任务删除函数

  • 源码
  • 1. 进入临界区
    • 1.1 第一步
    • 1.2 第二步
    • 1.3 第三步
    • 1.4 第四步
  • 2. 获取待删除任务的任务控制块TCB
  • 3. 从就绪/延迟列表中删除任务
  • 4. 从事件列表中删除任务
  • 5. 如果待删除任务是当前运行的任务
  • 6. 如果待删除任务是其它任务
  • 7. 退出临界区
    • 7.1 第一步
    • 7.2 第二步
    • 7.3 第三步
    • 7.4 第四步
  • 8. 如果待删除的任务不是当前运行的任务
  • 9. 如果待删除的任务不是当前运行的任务

  1. 介绍FreeRTOS任务删除函数的执行过程,逐行分析源代码。
  2. 要使用任务删除函数vTaskDelete,需要配置宏INCLUDE_vTaskDelete为1。
  3. 删除任务函数vTaskDelete的参数为待删除任务的任务句柄(即任务控制块)。
  4. 当函数参数为NULL时,代表删除的是调用函数的任务本身(即正在运行的任务)。

源码

/* 示例,在正在运行的任务中调用任务删除函数。*/
vTaskDelete(NULL); 
/* 任务删除 */
#if ( INCLUDE_vTaskDelete == 1 ) /* 需要INCLUDE_vTaskDelete宏配置为1 */void vTaskDelete( TaskHandle_t xTaskToDelete ) /* 函数参数为待删除任务的任务句柄,可以用NULL代替当前任务句柄。 */{TCB_t * pxTCB;taskENTER_CRITICAL(); /* 进入临界区,本质是关闭全局中断。 */{/* If null is passed in here then it is the calling task that is* being deleted.* 如果在此处传递NULL,则删除的是调用函数的任务本身。*/pxTCB = prvGetTCBFromHandle( xTaskToDelete );/* Remove task from the ready/delayed list.* 从就绪/延迟列表中删除任务* 如果删除后列表中没有列表项,则uxListRemove返回0*//* 将任务控制块的成员状态列表项xStateListItem从列表中移除 */if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ){taskRESET_READY_PRIORITY( pxTCB->uxPriority );}else{mtCOVERAGE_TEST_MARKER();}/* Is the task waiting on an event also?* 任务是否也在等待事件?* 任务控制块的成员xEventListItem是否挂载在其他列表中*/if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ){/* 将事件列表项从等待事件列表中移出 */( void ) uxListRemove( &( pxTCB->xEventListItem ) );}else{mtCOVERAGE_TEST_MARKER();}/* Increment the uxTaskNumber also so kernel aware debuggers can* detect that the task lists need re-generating.  This is done before* portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will* not return.* 同时自增uxTaskNumber,以便内核感知调试器可以检测到任务列表需要重新生成。* 这是在portPRE_TASK_DELETE_HOOK之前完成的,因为在Windows端口中,宏不会返回*/uxTaskNumber++; /* 任务列表需要重新生成 *//* 删除的是调用任务本身时 */if( pxTCB == pxCurrentTCB ){/* A task is deleting itself.  This cannot complete within the* task itself, as a context switch to another task is required.* Place the task in the termination list.  The idle task will* check the termination list and free up any memory allocated by* the scheduler for the TCB and stack of the deleted task.* 一个任务正在删除自己。* 这无法在任务本身内完成,因为需要切换到另一个任务的上下文。* 将任务放入等待结束列表中。* 空闲任务将检查等待结束列表,并释放调度器为准备删除任务分配的TCB和堆栈内存。*/vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );/* Increment the ucTasksDeleted variable so the idle task knows* there is a task that has been deleted and that it should therefore* check the xTasksWaitingTermination list.* 递增ucTasksDeleted变量,以便空闲任务知道有一个任务已被删除,* 因此它应该检查xTasksWaitingTermination列表。*/++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port.* 在调用portPRE_TASK_delete_hook之前调用delete钩子,* 因为portPRE_TAS K_delete_ hook在Win32端口中不返回。*/traceTASK_DELETE( pxTCB );/* The pre-delete hook is primarily for the Windows simulator,* in which Windows specific clean up operations are performed,* after which it is not possible to yield away from this task -* hence xYieldPending is used to latch that a context switch is* required.* 预删除挂钩主要用于Windows模拟器,* 在该模拟器中执行特定于Windows的清理操作,之后不可能放弃此任务,* 因此xYieldPending用于锁定需要进行上下文切换。*/portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );}else{--uxCurrentNumberOfTasks; /* 当前任务个数自减一 */traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to* the task that has just been deleted.* 重置下一个预期的解锁时间,以防它引用了刚刚被删除的任务*/prvResetNextTaskUnblockTime();}}taskEXIT_CRITICAL(); /* 退出临界区,本质是开启全局中断 *//* If the task is not deleting itself, call prvDeleteTCB from outside of* critical section. If a task deletes itself, prvDeleteTCB is called* from prvCheckTasksWaitingTermination which is called from Idle task.* 如果任务不是删除自己,请从临界区外部调用prvDeleteTCB。* 如果任务删除自己,则从空闲任务调用的prvCheckTasksWaitingTermination中调用prvDeleteTCB删除任务*/if( pxTCB != pxCurrentTCB ){prvDeleteTCB( pxTCB );}/* Force a reschedule if it is the currently running task that has just* been deleted.* 如果删除的是当前正在运行的任务,则强制重新开启一次任务调度*/if( xSchedulerRunning != pdFALSE ) /* 任务调度器正在运行中 */{if( pxTCB == pxCurrentTCB ) /* 删除的是当前正在运行的任务 */{configASSERT( uxSchedulerSuspended == 0 );portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}}#endif /* INCLUDE_vTaskDelete */

1. 进入临界区

taskENTER_CRITICAL(); /* 进入临界区,本质是关闭全局中断。 */

1.1 第一步

#define taskENTER_CRITICAL()               portENTER_CRITICAL() /* 从任务中进入临界区 */

1.2 第二步

#define portENTER_CRITICAL()  vPortEnterCritical()

1.3 第三步

void vPortEnterCritical( void )
{portDISABLE_INTERRUPTS();ulCriticalNesting++;
}

1.4 第四步

#define portDISABLE_INTERRUPTS() __asm(" setc INTM") /* 关闭全局中断 */

2. 获取待删除任务的任务控制块TCB

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; /* 指向当前运行的任务控制块。 */
/** Several functions take a TaskHandle_t parameter that can optionally be NULL,* where NULL is used to indicate that the handle of the currently executing* task should be used in place of the parameter.  This macro simply checks to* see if the parameter is NULL and returns a pointer to the appropriate TCB.* 有几个函数接受一个TaskHandle_t参数,该参数可以选择设置为NULL,* 其中NULL用于表示使用当前正在执行的任务的句柄来代替该参数。* 此宏只是检查参数是否为NULL,并返回指向相应TCB的指针。*/
#define prvGetTCBFromHandle( pxHandle )    ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) )

3. 从就绪/延迟列表中删除任务

/* Remove task from the ready/delayed list.* 从就绪/延迟列表中删除任务* 如果删除后列表中没有列表项,则返回0*/
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{taskRESET_READY_PRIORITY( pxTCB->uxPriority );
}
else
{mtCOVERAGE_TEST_MARKER();
}
/* 从列表中移除待移除的列表项 */
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{/* The list item knows which list it is in.  Obtain the list from the list* item.* 从列表项的成员pxContainer可以知道它在哪个列表中。从列表项中获取列表。* */List_t * const pxList = pxItemToRemove->pxContainer;/* 将列表项从列表中移除 */pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing.* 仅在决策覆盖率测试期间使用。*/mtCOVERAGE_TEST_DELAY();/* Make sure the index is left pointing to a valid item.* 确保索引指向有效项*/if( pxList->pxIndex == pxItemToRemove ) /* 如果列表的列表索引号指向待移除的列表项 */{pxList->pxIndex = pxItemToRemove->pxPrevious; /* 将索引号指向待移除列表项的前一个列表项 */}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL; /* 将待删除列表项的成员pxContainer设置为NULL,表示其不属于任何列表 */( pxList->uxNumberOfItems )--; /* 列表的列表项个数减一 */return pxList->uxNumberOfItems; /* 返回列表中剩余的列表项个数 */
}

4. 从事件列表中删除任务

/* Is the task waiting on an event also?* 任务是否也在等待事件?* 任务控制块的成员xEventListItem是否挂载在其他列表中*/
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{/* 将事件列表项从等待事件列表中移出 */( void ) uxListRemove( &( pxTCB->xEventListItem ) );
}
else
{mtCOVERAGE_TEST_MARKER();
}
/** Return the list a list item is contained within (referenced from).* 返回列表项所挂载的列表** @param pxListItem The list item being queried. pxListItem表示正在查询的列表项。* @return A pointer to the List_t object that references the pxListItem.  指向挂载pxListItem的List_t对象的指针*/
#define listLIST_ITEM_CONTAINER( pxListItem )            ( ( pxListItem )->pxContainer )

5. 如果待删除任务是当前运行的任务

  1. 将列表项xStateListItem按尾部插入法挂载到xTasksWaitingTermination列表中
  2. 变量uxDeletedTasksWaitingCleanUp自增一,以供空闲任务使用。
/* 删除的是调用任务本身时 */
if( pxTCB == pxCurrentTCB )
{/* A task is deleting itself.  This cannot complete within the* task itself, as a context switch to another task is required.* Place the task in the termination list.  The idle task will* check the termination list and free up any memory allocated by* the scheduler for the TCB and stack of the deleted task.* 一个任务正在删除自己。* 这无法在当前任务执行内部完成,因为还需要切换到另一个任务的上下文。* 因此将待删除任务放入等待结束任务列表中。* 空闲任务将检查等待结束任务列表,并释放调度器为待删除任务分配的TCB和堆栈内存。*/vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );/* Increment the ucTasksDeleted variable so the idle task knows* there is a task that has been deleted and that it should therefore* check the xTasksWaitingTermination list.* 递增ucTasksDeleted变量,以便空闲任务知道有一个任务已被删除,* 因此它应该检查xTasksWaitingTermination列表。* */++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port.* 在调用portPRE_TASK_delete_hook之前调用delete钩子,* 因为portPRE_TAS K_delete_ hook在Win32端口中不返回。* */traceTASK_DELETE( pxTCB );/* The pre-delete hook is primarily for the Windows simulator,* in which Windows specific clean up operations are performed,* after which it is not possible to yield away from this task -* hence xYieldPending is used to latch that a context switch is* required.* 预删除挂钩主要用于Windows模拟器,* 在该模拟器中执行特定于Windows的清理操作,之后不可能放弃此任务,* 因此xYieldPending用于锁定需要进行上下文切换。* */portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
}

6. 如果待删除任务是其它任务

--uxCurrentNumberOfTasks; /* 当前任务个数自减一 */
traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to* the task that has just been deleted.* 重置下一个预期的解锁时间,以防它引用了刚刚被删除的任务,即下一个解除等待准备运行的任务就是待删除任务。*/
prvResetNextTaskUnblockTime();
/* 重置下一个任务解锁时间 */
static void prvResetNextTaskUnblockTime( void )
{if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) /* 延迟任务列表是否为空 */{/* The new current delayed list is empty.  Set xNextTaskUnblockTime to* the maximum possible value so it is  extremely unlikely that the* if( xTickCount >= xNextTaskUnblockTime ) test will pass until* there is an item in the delayed list.* 当前新的延迟列表为空。将xNextTaskUnblockTime设置为最大可能值*/xNextTaskUnblockTime = portMAX_DELAY;}else{/* The new current delayed list is not empty, get the value of* the item at the head of the delayed list.  This is the time at* which the task at the head of the delayed list should be removed* from the Blocked state.* 当前新的延迟列表不为空,请获取延迟列表头部项目的值。* 此时,应将延迟列表开头的任务从“阻塞”状态中删除。* 即准备让下一个被阻塞的任务开始执行*/xNextTaskUnblockTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxDelayedTaskList );}
}
/** Access macro to determine if a list contains any items.  The macro will* only have the value true if the list is empty.* 访问宏以确定列表是否包含任何列表项。只有当列表为空时,宏才会具有值true。*/
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. 指向当前正在使用的延迟任务列表*/
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/** Access macro to retrieve the value of the list item at the head of a given list. * 访问宏以检索给定列表开头的列表项的值*/
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )        ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) /* 末尾列表项的下一个列表项即为头部列表项。 */
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. 在调度程序启动之前,已初始化为portMAX_DELAY*/

7. 退出临界区

taskEXIT_CRITICAL(); /* 退出临界区,本质是开启全局中断 */

7.1 第一步

#define taskEXIT_CRITICAL()                portEXIT_CRITICAL()

7.2 第二步

#define portEXIT_CRITICAL()   vPortExitCritical()

7.3 第三步

void vPortExitCritical( void )
{ulCriticalNesting--;if( ulCriticalNesting == 0 ){portENABLE_INTERRUPTS();}
}

7.4 第四步

#define portENABLE_INTERRUPTS()   __asm(" clrc INTM") /* 打开全局中断 */

8. 如果待删除的任务不是当前运行的任务

/* If the task is not deleting itself, call prvDeleteTCB from outside of* critical section. If a task deletes itself, prvDeleteTCB is called* from prvCheckTasksWaitingTermination which is called from Idle task.* 如果任务不是删除自己,请从临界区外部调用prvDeleteTCB。* 如果任务删除自己,则从空闲任务调用的prvCheckTasksWaitingTermination中调用prvDeleteTCB删除任务*/
if( pxTCB != pxCurrentTCB )
{prvDeleteTCB( pxTCB );
}
/* 删除任务控制块,根据分配内存的方式释放TCB和堆栈内存 */
#if ( INCLUDE_vTaskDelete == 1 )static void prvDeleteTCB( TCB_t * pxTCB ){/* This call is required specifically for the TriCore port.  It must be* above the vPortFree() calls.  The call is also used by ports/demos that* want to allocate and clean RAM statically.* 此调用是TriCore端口特有的。它必须位于vPortFree调用之上。* 该调用也被希望静态分配和清理RAM的端口/演示使用。* */portCLEAN_UP_TCB( pxTCB );#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ){/* Free up the memory allocated for the task's TLS Block. */configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock );}#endif#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ){/* The task can only have been allocated dynamically - free both* the stack and TCB.* 该任务只能是被动态分配,需要释放堆栈和TCB* */vPortFreeStack( pxTCB->pxStack );vPortFree( pxTCB );}#elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */{/* The task could have been allocated statically or dynamically, so* check what was statically allocated before trying to free the* memory.* 任务可以静态或动态分配,因此在尝试释放内存之前,请检查静态分配的内容* */if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ){/* Both the stack and TCB were allocated dynamically, so both* must be freed.* 堆栈和TCB都是动态分配的,因此必须释放它们。* */vPortFreeStack( pxTCB->pxStack );vPortFree( pxTCB );}else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ){/* Only the stack was statically allocated, so the TCB is the* only memory that must be freed.* 只有堆栈是静态分配的,因此TCB是唯一必须释放的内存。* */vPortFree( pxTCB );}else{/* Neither the stack nor the TCB were allocated dynamically, so* nothing needs to be freed.* 堆栈和TCB都不是动态分配的,因此不需要释放任何内容* */configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB );mtCOVERAGE_TEST_MARKER();}}#endif /* configSUPPORT_DYNAMIC_ALLOCATION */}#endif /* INCLUDE_vTaskDelete */

9. 如果待删除的任务不是当前运行的任务

/* Force a reschedule if it is the currently running task that has just* been deleted.* 如果删除的是当前正在运行的任务,则强制重新开启一次任务调度*/
if( xSchedulerRunning != pdFALSE ) /* 任务调度器正在运行中 */
{if( pxTCB == pxCurrentTCB ) /* 删除的是当前正在运行的任务 */{configASSERT( uxSchedulerSuspended == 0 );portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}
}
PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;
#ifndef portYIELD_WITHIN_API#define portYIELD_WITHIN_API    portYIELD
#endif
#define portYIELD() do{bYield = 1; __asm(" INTR INT14");}while(0)

相关文章:

《FreeRTOS任务删除篇》

任务删除函数 源码1. 进入临界区1.1 第一步1.2 第二步1.3 第三步1.4 第四步 2. 获取待删除任务的任务控制块TCB3. 从就绪/延迟列表中删除任务4. 从事件列表中删除任务5. 如果待删除任务是当前运行的任务6. 如果待删除任务是其它任务7. 退出临界区7.1 第一步7.2 第二步7.3 第三步…...

递归算法专题一>Pow(x, n)

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …...

数据结构第一讲

数据结构定义 算法的定义 什么是好算法&#xff1f; 空间复杂度 时间复杂度 例子1 打印1到N之间的正整数 有递归和循环两种方法实现。 但是在数字变大后&#xff0c;递归的方法会导致内存占用过多而崩溃。 而循环则不会 例子2 写程序给定多项式在X处的值 从里往外算的算…...

SHELL笔记(循环)

在 Shell 编程中&#xff0c;循环结构是极为重要的一部分&#xff0c;它能够让我们轻松地重复执行特定的代码块&#xff0c;从而高效地处理各种重复性任务。本文将详细介绍 Shell 中常见的循环结构&#xff0c;包括 for 循环、while 循环和 until 循环&#xff0c;并通过具体的…...

SpringBoot多文件上传

多文件上传是在单文件上传的基础上修改而来&#xff0c;不了解单文件上传可以参考上一篇。以下在将修改部分展示如下&#xff1a; 一、修改upload.html文件&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title&g…...

MyBatis-数据库连接池、属性文件config.properties、类名简化、MyBatis的整体架构

一、数据库连接池 1、概述 存储实现创建好的连接对象的容器 2、优点 避免了频繁创建和销毁连接对象 3、使用 在使用到连接对象时可在数据库连接池中直接获取 4、实现 不需要我们去实现,框架和一些第三方有现成的组件&#xff08;C3P0、ADCP、德鲁伊(阿里巴巴)&#xff…...

Flink-Source的使用

Data Sources 是什么呢&#xff1f;就字面意思其实就可以知道&#xff1a;数据来源。 Flink 做为一款流式计算框架&#xff0c;它可用来做批处理&#xff0c;也可以用来做流处理&#xff0c;这个 Data Sources 就是数据的来源地。 flink在批/流处理中常见的source主要有两大类…...

C0031.在Clion中使用mingw编译器来编译opencv的配置方法

mingw编译器编译opencv库的配置方法...

Android——连接MySQL(Java版)

Android——连接MySQL(Java版) 目录&#xff1a; Android——连接MySQL(Java版)一、JDBC1、什么是JDBC2、载入JDBC3、创建JDBC的工具类 二、使用数据库 一、JDBC 1、什么是JDBC JDBC全称Java Database Connectivity&#xff0c;译为Java语言连接数据库&#xff0c;是sun公司制…...

「四」体验HarmonyOS端云一体化开发模板——工程目录结构与云侧工程一键部署AGC云端

关于作者 白晓明 宁夏图尔科技有限公司董事长兼CEO、坚果派联合创始人 华为HDE、润和软件HiHope社区专家、鸿蒙KOL、仓颉KOL 华为开发者学堂/51CTO学堂/CSDN学堂认证讲师 开放原子开源基金会2023开源贡献之星 「目录」 「一」HarmonyOS端云一体化概要 「二」体验HarmonyOS端云一…...

Kotlin:后端开发的新宠

在当今的软件开发领域&#xff0c;编程语言的选择对于项目的成功至关重要。Kotlin&#xff0c;一种由 JetBrains 开发的编程语言&#xff0c;近年来在后端领域逐渐崭露头角&#xff0c;展现出了广阔的应用前景。 一、Kotlin 简介 Kotlin 是一种基于 JVM&#xff08;Java Virt…...

SSM全家桶 1.Maven

或许总要彻彻底底地绝望一次 才能重新再活一次 —— 24.11.20 maven在如今的idea中已经实现自动配置&#xff0c;不需要我们手动下载 一、Maven的简介和快速入门 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件)&#xff0c;使用 Maven 可以自动化构建测试、打包和发…...

SpringBoot 集成 html2Pdf

一、概述&#xff1a; 1. springboot如何生成pdf&#xff0c;接口可以预览可以下载 2. vue下载通过bold如何下载 3. 一些细节&#xff1a;页脚、页眉、水印、每一页得样式添加 二、直接上代码【主要是一个记录下次开发更快】 模板位置 1. 导入pom包 <dependency><g…...

利用 Watchtower 自动监听并更新正在运行的 Docker 容器

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 大部分 VPS 和 NAS 用户或多或少都有用 Docker 来部署一些 Self-hosting 的服务&#xff0c;其中大部分项目都是开源项目&#xff0c;更新频率非常高&#xff0c;特别是一些版本 0.x 的项目&#xff0c;及…...

Nodejs开发仿马蜂窝旅游小程序API接口,服务器端开发,商家后台 Vue3+微信小程序+koa+mongodb+node.js

文章目录 &#x1f680; 开启您的互联网创业新篇章一、&#x1f525; 课程亮点&#xff1a;二、&#x1f310; 适合人群&#xff1a;学习这个课程后&#xff0c;您将会收获到三、旅游后台管理系统1.后台登录界面2.后台首页 四、前台旅游小程序1.首页展示2.目的地界面3.搜索功能…...

极限失控的大模型使电力系统面临的跨域攻击风险及应对措施

目录&#xff1a; 0 引言 1 就大模型发生极限失控的风险进行讨论的必要性、紧迫性 1.1 预训练的数据来源 1.2 能力涌现与不可解释性 1.3 大模型与物质世界的连接 1.4 数量效应与失控 1.5 大模型发生极限失控的风险 1.5.1 人工智能反叛所需要素能力的拼图 1.5.2 火种源…...

mybatis-plus方法无效且字段映射失败错误排查

问题&#xff1a; Invalid bound statement (not found): com.htlc.assetswap.mapper.WalletMapper.insert&#xff0c;并且select * 进行查询时带下划线的字段未成功映射。 排查&#xff1a; 1.检查WalletMapper接口&#xff0c;确保继承自BaseMapper 2.启用驼峰命名法映射。a…...

librdns一个开源DNS解析库

原文地址&#xff1a;librdns一个开源DNS解析库 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 介绍 librdns是一个开源的异步多功能插件式的解析器&#xff0c;用于DNS解析。 源代码地址&#xff1a;GitHub - vstakhov/librdns: Asynchrono…...

Unity3D 逻辑服的Entity, ComponentData与System划分详解

前言 在Unity3D中&#xff0c;逻辑服(Entity, ComponentData和System)是一种非常高效的组件化设计模式&#xff0c;它可以帮助开发者更好地管理游戏中的实体和逻辑。本文将详细介绍Unity3D逻辑服的概念以及如何实现Entity、ComponentData和System的划分。 对惹&#xff0c;这…...

跟《经济学人》学英文:2024年11月23日这期 Why British MPs should vote for assisted dying

Why British MPs should vote for assisted dying A long-awaited liberal reform is in jeopardy in jeopardy&#xff1a;在危险中 jeopardy&#xff1a;美 [ˈdʒepərdi] 危险&#xff1b;危机&#xff1b;风险&#xff1b; 原文&#xff1a; THIS NEWSPAPER believes …...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...