OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【时间管理】

news2024/11/14 14:04:10

往期知识点记录:

  • 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
  • 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
  • 子系统开发内核
  • 轻量系统内核(LiteOS-M)
  • 轻量系统内核(LiteOS-M)【中断管理】
  • 轻量系统内核(LiteOS-M)【任务管理】
  • 轻量系统内核(LiteOS-M)【内存管理】
  • 轻量系统内核(LiteOS-M)【内核通信机制】
  • 轻量系统内核(LiteOS-M)【时间管理】
  • 轻量系统内核(LiteOS-M)【扩展组件】
  • 轻量系统内核(LiteOS-M)【内存调测】
  • 轻量系统内核(LiteOS-M)【异常调测】
  • 轻量系统内核(LiteOS-M)【Trace调测】
  • 轻量系统内核(LiteOS-M)【LMS调测】
  • 轻量系统内核(LiteOS-M)【SHELL】
  • 小型系统内核(LiteOS-A)【概述】
  • 小型系统内核(LiteOS-A)【内核启动】
  • 小型系统内核(LiteOS-A)【中断及异常处理】
  • 标准系统内核(Linux)【New IP内核协议栈】
  • 标准系统内核(Linux)【内核增强特性 > 任务调度】
  • 持续更新中……

基本概念

时间管理以系统时钟为基础。时间管理提供给应用程序所有和时间有关的服务。系统时钟是由定时/计数器产生的输出脉冲触发中断而产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。

系统时钟也称为时标或者Tick。一个Tick的时长可以静态配置。用户是以秒、毫秒为单位计时,而操作系统时钟计时是以Tick为单位的,当用户需要对系统操作时,例如任务挂起、延时等,输入秒为单位的数值,此时需要时间管理模块对二者进行转换。

Tick与秒之间的对应关系可以配置。

  • Cycle 系统最小的计时单位。Cycle的时长由系统主频决定,系统主频就是每秒钟的Cycle数。

  • Tick Tick是操作系统的基本时间单位,对应的时长由系统主频及每秒Tick数决定,由用户配置。

OpenHarmony系统的时间管理模块提供时间转换、统计、延迟功能以满足用户对时间相关需求的实现。

开发指导

用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系,以及需要使用到时间管理模块的接口。

接口说明

OpenHarmony LiteOS-A内核的时间管理提供以下几种功能,接口详细信息可查看API参考。

表1 时间管理相关接口说明:

功能分类接口描述
时间转换LOS_MS2Tick:毫秒转换成Tick
LOS_Tick2MS:Tick转换成毫秒
时间统计LOS_TickCountGet:获取当前Tick数
LOS_CyclePerTickGet:每个Tick的cycle数

开发流程

  1. 调用时间转换接口;

  2. 获取系统Tick数完成时间统计等。

说明:

  • 获取系统Tick数需要在系统时钟使能之后。

  • 时间管理不是单独的功能模块,依赖于los_config.h中的OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。

  • 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间计算。

编程实例

前置条件:

  • 配置好LOSCFG_BASE_CORE_TICK_PER_SECOND,即系统每秒的Tick数,范围(0, 1000)。

  • 配置好OS_SYS_CLOCK 系统时钟频率,单位:Hz。

示例代码

时间转换:

VOID Example_TransformTime(VOID)
{
    UINT32 uwMs;
    UINT32 uwTick;
    uwTick = LOS_MS2Tick(10000); //10000 ms数转换为Tick数
    PRINTK("uwTick = %d \n",uwTick);
    uwMs= LOS_Tick2MS(100); //100 Tick数转换为ms数
    PRINTK("uwMs = %d \n",uwMs);
}

时间统计和时间延迟:

VOID Example_GetTime(VOID)
{
    UINT32 uwcyclePerTick;
    UINT64 uwTickCount;

    uwcyclePerTick = LOS_CyclePerTickGet(); //每个Tick多少Cycle数
    if(0 != uwcyclePerTick)
    {
        PRINTK("LOS_CyclePerTickGet = %d \n", uwcyclePerTick);
    }

    uwTickCount = LOS_TickCountGet(); //获取Tick数
    if(0 != uwTickCount)
    {
        PRINTK("LOS_TickCountGet = %d \n", (UINT32)uwTickCount);
    }
    LOS_TaskDelay(200);//延迟200 Tick
    uwTickCount = LOS_TickCountGet();
    if(0 != uwTickCount)
    {
        PRINTK("LOS_TickCountGet after delay = %d \n", (UINT32)uwTickCount);
    }
}

结果验证

编译运行的结果如下:

时间转换:

uwTick = 10000 
uwMs = 100

时间统计和时间延迟:

LOS_CyclePerTickGet = 49500 
LOS_TickCountGet = 347931
LOS_TickCountGet after delay = 348134

软件定时器

基本概念

软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。

硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,OpenHarmony LiteOS-A内核提供软件定时器功能。

软件定时器扩展了定时器的数量,允许创建更多的定时业务。

软件定时器支持以下功能:

  • 静态裁剪:能通过宏关闭软件定时器功能。
  • 软件定时器创建。
  • 软件定时器启动。
  • 软件定时器停止。
  • 软件定时器删除。
  • 软件定时器剩余Tick数获取。

运行机制

软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los_config.h中的LOSCFG_BASE_CORE_SWTMR_LIMIT宏配置。

软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。同一时刻设置的定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。

软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,OpenHarmony系统会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。

当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。

Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。

定时器状态:

  • OS_SWTMR_STATUS_UNUSED(未使用) 系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。

  • OS_SWTMR_STATUS_CREATED(创建未启动/停止) 在未使用状态下调用LOS_SwtmrCreate接口或者启动后调用LOS_SwtmrStop接口后,定时器将变成该状态。

  • OS_SWTMR_STATUS_TICKING(计数) 在定时器创建后调用LOS_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。

定时器模式:

  • 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。

  • 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。

  • 第三类也是单次触发定时器,但与第一类不同之处在于这类定时器超时后不会自动删除,需要调用定时器删除接口删除定时器。

开发指导

接口说明

OpenHarmony LiteOS-A内核的软件定时器模块提供以下几种功能。

表1 软件定时器接口说明

功能分类接口描述
创建、删除定时器LOS_SwtmrCreate:创建软件定时器
LOS_SwtmrDelete:删除软件定时器
启动、停止定时器LOS_SwtmrStart:启动软件定时器
LOS_SwtmrStop:停止软件定时器
获得软件定时剩余Tick数LOS_SwtmrTimeGet:获得软件定时器剩余Tick数

开发流程

软件定时器的典型开发流程:

  1. 配置软件定时器。

    • 确认配置项LOSCFG_BASE_CORE_SWTMR和LOSCFG_BASE_IPC_QUEUE为打开状态;
    • 配置LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数;
    • 配置OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度;
  2. 创建定时器LOS_SwtmrCreate。

    • 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器;
    • 返回函数运行结果,成功或失败;
  3. 启动定时器LOS_SwtmrStart。

  4. 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。

  5. 停止定时器LOS_SwtmrStop。

  6. 删除定时器LOS_SwtmrDelete。

说明:

  • 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。

  • 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。

  • 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。

  • 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。

  • 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。

编程实例

前置条件

  • 在los_config.h中,将LOSCFG_BASE_CORE_SWTMR配置项打开。

  • 配置好LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数。

  • 配置好OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度。

编程示例

#include "los_swtmr.h"

void Timer1_Callback(uint32_t arg);
void Timer2_Callback(uint32_t arg);

UINT32 g_timercount1 = 0;
UINT32 g_timercount2 = 0;

void Timer1_Callback(uint32_t arg) // 回调函数1
{
    unsigned long tick_last1;
    g_timercount1++;
    tick_last1=(UINT32)LOS_TickCountGet(); // 获取当前Tick数
    PRINTK("g_timercount1=%d\n",g_timercount1);
    PRINTK("tick_last1=%d\n",tick_last1);
}

void Timer2_Callback(uint32_t arg) // 回调函数2
{
    unsigned long tick_last2;
    tick_last2=(UINT32)LOS_TickCountGet();
    g_timercount2 ++;
    PRINTK("g_timercount2=%d\n",g_timercount2);
    PRINTK("tick_last2=%d\n",tick_last2);
}

void Timer_example(void)
{
    UINT16 id1;
    UINT16 id2; // timer id
    UINT32 uwTick;

    /* 创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */
    LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1);

    /* 创建周期性软件定时器,每100Tick数执行回调函数2 */
    LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1);
    PRINTK("create Timer1 success\n");

    LOS_SwtmrStart (id1); //启动单次软件定时器
    dprintf("start Timer1 success\n");
    LOS_TaskDelay(200); // 延时200Tick数
    LOS_SwtmrTimeGet(id1, &uwTick); // 获得单次软件定时器剩余Tick数
    PRINTK("uwTick =%d\n", uwTick);

    LOS_SwtmrStop(id1); // 停止软件定时器
    PRINTK("stop Timer1 success\n");

    LOS_SwtmrStart(id1);
    LOS_TaskDelay(1000);
    LOS_SwtmrDelete(id1); // 删除软件定时器
    PRINTK("delete Timer1 success\n");

    LOS_SwtmrStart(id2); // 启动周期性软件定时器
    PRINTK("start Timer2\n");

    LOS_TaskDelay(1000);
    LOS_SwtmrStop(id2);
    LOS_SwtmrDelete(id2);
}

运行结果

create Timer1 success
start Timer1 success
uwTick =800
stop Timer1 success
g_timercount1=1
tick_last1=1201
delete Timer1 success
start Timer2
g_timercount2 =1
tick_last1=1301
g_timercount2 =2
tick_last1=1401
g_timercount2 =3
tick_last1=1501
g_timercount2 =4
tick_last1=1601
g_timercount2 =5
tick_last1=1701
g_timercount2 =6
tick_last1=1801
g_timercount2 =7
tick_last1=1901
g_timercount2 =8
tick_last1=2001
g_timercount2 =9
tick_last1=2101
g_timercount2 =10
tick_last1=2201

原子操作

基本概念

在支持多任务的操作系统中,修改一块内存区域的数据需要“读取-修改-写入”三个步骤。然而同一内存区域的数据可能同时被多个任务访问,如果在修改数据的过程中被其他任务打断,就会造成该操作的执行结果无法预知。

使用开关中断的方法固然可以保证多任务执行结果符合预期,但是显然这种方法会影响系统性能。

ARMv6架构引入了LDREX和STREX指令,以支持对共享存储器更缜密的非阻塞同步。由此实现的原子操作能确保对同一数据的“读取-修改-写入”操作在它的执行期间不会被打断,即操作的原子性。

运行机制

OpenHarmony系统通过对ARMv6架构中的LDREX和STREX进行封装,向用户提供了一套原子性的操作接口。

  • LDREX Rx, [Ry] 读取内存中的值,并标记对该段内存的独占访问:

    • 读取寄存器Ry指向的4字节内存数据,保存到Rx寄存器中。
    • 对Ry指向的内存区域添加独占访问标记。
  • STREX Rf, Rx, [Ry] 检查内存是否有独占访问标记,如果有则更新内存值并清空标记,否则不更新内存:

    • 有独占访问标记
      • 将寄存器Rx中的值更新到寄存器Ry指向的内存。
      • 标志寄存器Rf置为0。
    • 没有独占访问标记
      • 不更新内存。
      • 标志寄存器Rf置为1。
  • 判断标志寄存器

    • 标志寄存器为0时,退出循环,原子操作结束。
    • 标志寄存器为1时,继续循环,重新进行原子操作。

开发指导

接口说明

OpenHarmony LiteOS-A内核的原子操作模块提供以下几种功能。

表1 原子操作接口说明

功能分类接口名称描述
LOS_AtomicRead读取32bit原子数据
LOS_Atomic64Read读取64bit原子数据
LOS_AtomicSet设置32bit原子数据
LOS_Atomic64Set设置64bit原子数据
LOS_AtomicAdd对32bit原子数据做加法
LOS_Atomic64Add对64bit原子数据做加法
LOS_AtomicInc对32bit原子数据做加1
LOS_Atomic64Inc对64bit原子数据做加1
LOS_AtomicIncRet对32bit原子数据做加1并返回
LOS_Atomic64IncRet对64bit原子数据做加1并返回
LOS_AtomicSub对32bit原子数据做减法
LOS_Atomic64Sub对64bit原子数据做减法
LOS_AtomicDec对32bit原子数据做减1
LOS_Atomic64Dec对64bit原子数据做减1
LOS_AtomicDecRet对32bit原子数据做减1并返回
LOS_Atomic64DecRet对64bit原子数据做减1并返回
交换LOS_AtomicXchgByte交换8bit内存数据
交换LOS_AtomicXchg16bits交换16bit内存数据
交换LOS_AtomicXchg32bits交换32bit内存数据
交换LOS_AtomicXchg64bits交换64bit内存数据
先比较后交换LOS_AtomicCmpXchgByte比较相同后交换8bit内存数据
先比较后交换LOS_AtomicCmpXchg16bits比较相同后交换16bit内存数据
先比较后交换LOS_AtomicCmpXchg32bits比较相同后交换32bit内存数据
先比较后交换LOS_AtomicCmpXchg64bits比较相同后交换64bit内存数据

开发流程

有多个任务对同一个内存数据进行加减或交换等操作时,使用原子操作保证结果的可预知性。

说明: 原子操作接口仅支持整型数据。

编程实例

实例描述

调用原子操作相关接口,观察结果:

  1. 创建两个任务

    • 任务一用LOS_AtomicInc对全局变量加100次。
    • 任务二用LOS_AtomicDec对全局变量减100次。
  2. 子任务结束后在主任务中打印全局变量的值。

示例代码

示例代码如下:

#include "los_hwi.h"
#include "los_atomic.h"
#include "los_task.h"

UINT32 g_testTaskId01;
UINT32 g_testTaskId02;
Atomic g_sum;
Atomic g_count;

UINT32 Example_Atomic01(VOID)
{
    int i = 0;
    for(i = 0; i < 100; ++i) {
        LOS_AtomicInc(&g_sum);
    }

    LOS_AtomicInc(&g_count);
    return LOS_OK;
}

UINT32 Example_Atomic02(VOID)
{
    int i = 0;
    for(i = 0; i < 100; ++i) {
        LOS_AtomicDec(&g_sum);
    }

    LOS_AtomicInc(&g_count);
    return LOS_OK;
}

UINT32 Example_AtomicTaskEntry(VOID)
{
    TSK_INIT_PARAM_S stTask1={0};
    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Atomic01;
    stTask1.pcName       = "TestAtomicTsk1";
    stTask1.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    stTask1.usTaskPrio   = 4;
    stTask1.uwResved     = LOS_TASK_STATUS_DETACHED;

    TSK_INIT_PARAM_S stTask2={0};
    stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Atomic02;
    stTask2.pcName       = "TestAtomicTsk2";
    stTask2.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    stTask2.usTaskPrio   = 4;
    stTask2.uwResved     = LOS_TASK_STATUS_DETACHED;

    LOS_TaskLock();
    LOS_TaskCreate(&g_testTaskId01, &stTask1);
    LOS_TaskCreate(&g_testTaskId02, &stTask2);
    LOS_TaskUnlock();

    while(LOS_AtomicRead(&g_count) != 2);
    PRINTK("g_sum = %d\n", g_sum);

    return LOS_OK;
}

结果验证

g_sum = 0

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

在这里插入图片描述

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN/733GH/overview

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片
在这里插入图片描述

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

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

相关文章

围剿Model Y,小米SUV也来拼刺刀了

文 | AUTO芯球 作者 | 雷慢 马斯克真是被小米雷军盯上了&#xff0c; 前面小米SU7死磕Model 3&#xff0c; 现在小米SUV又来打Model Y了&#xff0c; 别不信啊&#xff0c;就刚刚&#xff0c;小米SUV出现了最大的曝光&#xff0c; 外观谍照&#xff0c;内饰中控台都曝光了…

RflySim工具链常见问题答疑

1. RflySim结合硬件能不能实现无人机颜色巡线呢&#xff1f; 可以&#xff0c;内置有一个通过相机识别来攻击小球的实验&#xff0c;可见&#xff1a;【RflySim安装路径】\RflySimAPIs\8.RflySimVision\1.BasicExps\1-VisionCtrlDemos\e3_ShootBall&#xff0c;不过要想实现无人…

Linux 进程3

进程地址空间 CPU读取数据都需要地址&#xff0c;在计算机中所有东西都是一种数据&#xff0c;包括我们的进程。 这是一个进程空间示意图&#xff0c;操作系统通过task_struct结构体链表来管理每一个进程&#xff0c;结构体里面有一个指针指向操作系统为进程开辟的一段空间&am…

博导团队指导、解读实验结果、SCI论文润色

表观组&#xff1a; DAP-seq:转录因子-DNA互作研究工具 ATAC-seq :染色质开放程度研究工具 H3K4me3 ChIP-seq:组蛋白甲基化修饰工具 BS-seq :DNA甲基化研究工具 H3K27ac ChIP-seq:组蛋白乙酰化修饰研究工具 Cut&Tag:转录因子研究工具 ChIP-seq:转录因子-DNA互作工具 互作组…

HTTP 教程

HTTP/HTTPS 简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff0c;超文本传输安全协议&#xff09;是用于在网络中传输信息的两种主要协议。它们定义了客户端和服务器…

PDF样本册如何分享到朋友圈

​想象一下&#xff0c;你刚刚参加了一场行业盛会&#xff0c;获取了一份包含最新行业动态、优秀案例的PDF样本册。你迫不及待地想要分享给身边的朋友&#xff0c;与他们共同学习、探讨。然而&#xff0c;传统的分享方式要么依赖纸质版&#xff0c;要么通过电子邮件&#xff0c…

C++模拟实现list:list、list类的初始化和尾插、list的迭代器的基本实现、list的完整实现、测试、整个list类等的介绍

文章目录 前言一、list二、list类的初始化和尾插三、list的迭代器的基本实现四、list的完整实现五、测试六、整个list类总结 前言 C模拟实现list&#xff1a;list、list类的初始化和尾插、list的迭代器的基本实现、list的完整实现、测试、整个list类等的介绍 一、list list本…

LeetCode讲解篇之220. 存在重复元素 III

文章目录 题目描述题解思路题解代码 题目描述 题解思路 我们可以考虑存储数组中连续indexDiff个数字&#xff0c;这样我们只需要在这连续的indexDiff个数字中查找相差小于等于valueDiff的两个数字的问题 对于该查找问题&#xff0c;我们可以考虑使用以valueDiff大小为一个桶&a…

自动化测试常用函数

目录 一、元素的定位 1、cssSelector 2、xpath &#xff08;1&#xff09;xpath 语法 1、获取HTML页面所有的节点 2、获取HTML页面指定的节点 3、获取一个节点中的直接子节点 4、获取一个节点的父节点 5、实现节点属性的匹配 6、使用指定索引的方式获取对应的节点内容…

MYSQL面试知识点手册

第一部分&#xff1a;MySQL 基础知识 1.1 MySQL 简介 MySQL 是世界上最流行的开源关系型数据库管理系统之一&#xff0c;它以性能卓越、稳定可靠和易用性而闻名。MySQL 主要应用在 Web 开发、大型互联网公司、企业级应用等场景&#xff0c;且广泛用于构建高并发、高可用的数据…

动态线程池(四)

动态线程池 dtp生命周期管理 生命周期相关类图 DtpExecutor EagerEtpExecutor OrderedDtpExecutor TaskWrapper任务包装器 MdcRunnable TaskWrappers NotifyEnum NoticeManager通知管理器 InvokerChain调用链

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿 人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;量化投资已逐渐成为金融行业的新趋势&#xff0c;对专业人才的需求日益迫切。本文将深入探讨一项针对AI与量化投资的人才培养计划&#xff0c;旨在为金融专业…

No operations allowed after statement closed

错误信息&#xff1a; The last packet successfully received from the server was 3,576,246 milliseconds ago. The last packet sent successfully to the server was 3,576,247 milliseconds ago. 参考解决方案 https://github.com/alibaba/druid/issues/5549 如果修改…

誉龙视音频 Third/TimeSyn 远程命令执行复现

0x01 漏洞描述&#xff1a; 誉龙公司定位为系统级的移动视音频记录解决方案提供商&#xff0c;凭借其深厚的行业经验&#xff0c;坚持自主研发&#xff0c;匠心打造记录仪领域行业生态&#xff0c;提供开放式的记录仪APK、GB28181 SDK、国网B协议、管理平台软件OEM。誉龙视音频…

leaflet加载GeoServer的WMS地图服务.md

leaflet加载GeoServer的WMS地图服务&#xff0c;该示例涵盖了涵盖了 “WMS图层加载、WMS图层动态投影、图层index顺序调整、图层添加、高德地图、腾讯地图OpenStreet地图”&#xff0c;WMS图层加载看代码中标注的核心代码部分即可。 <!DOCTYPE html> <html xmlns&qu…

湖南(用户访谈)源点咨询 市场调研中何种情况下选择定性方式?

湖南&#xff08;市场调研&#xff09;源点咨询认为&#xff0c;很多调研方法被分组为"定性调研方法"或"收集资料的定性方法"。 这反映了对定性调研的继承&#xfe63;&#xfe63;它的根源在于社会科学&#xff0c;尤其在社会学和人类学&#xff0c;还有…

AI大模型之旅-langchain结合glm4,faiss构建本地知识库

所需依赖如下&#xff1a; _libgcc_mutex0.1main _openmp_mutex5.11_gnu accelerate0.34.2pypi_0 aiofiles23.2.1pypi_0 aiohappyeyeballs2.4.0pypi_0 aiohttp3.10.5pypi_0 aiosignal1.3.1pypi_0 annotated-types0.7.0pypi_0 anyio4.4.0pypi_0 attrs24.2.0pypi_0 bitsandbytes…

Web开发:ABP框架3——入门级别的接口增删改查实现原理

一、上节回顾 运用了ABP框架&#xff0c;使用了EFcore进行增删改查 二、程序的入口 代码解说&#xff1a; public class Program // 定义程序主类 {public async static Task<int> Main(string[] args) // 主方法&#xff0c;返回状态码{// 配置Serilog日志Log.Logger…

如何给zip文件设置自动加密,保护压缩包不被随意打开

ZIP是日常生活和工作中经常用到的压缩文件格式&#xff0c;对于重要的文件&#xff0c;我们往往还会设置打开密码&#xff0c;保护压缩包不被随意打开。 如果每次压缩文件都要设置一次密码&#xff0c;操作久了还是有点麻烦&#xff0c;那有没有一种方法&#xff0c;只要压缩文…

数据库系统原理与应用【笔记总结】

笔记链接&#xff1a;CongSec电脑端可能需要科学上网&#xff0c;手机端不用 笔记部分展示&#xff1a; 笔记列表形式&#xff1a; 数据库系统概述 数据与信息 数据信息数据处理 数据管理技术的发展 人工管理阶段文件系统阶段数据库系统阶段 数据库系统的基本概念 数据库数据…