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

往期知识点记录:

  • 鸿蒙(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 TickuwTickCount = 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 idUINT32 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.xdnf.cn/news/145260.html

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

相关文章

百望云生态伙伴大会在北京、深圳、昆明三地举办,携手共赢数字化未来!

伴随着金税四期数电票、乐企加速扩围&#xff0c;激发了企业大量的财税数字化转型的需求&#xff0c;为财税服务市场注入了前所有未有的活力。2024年7月9日&#xff0c;百望云成功登陆港交所&#xff0c;成为港股“电子发票第一股”&#xff0c;加码财税业务布局&#xff0c;纵…

【C++ Primer Plus习题】16.10

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: #include <iostream> #include <string> #include <…

【刷题日记】15. 三数之和

15. 三数之和 两数之和可以用巧思也可以用map 三数之和会更加复杂一点&#xff0c;且这道题还需要考虑避免重复答案&#xff01; 思路&#xff1a; 特判&#xff1a;检如果nums 为 null 或长度小于 3直接返回空数组。排序&#xff1a;使用 sort对数组进行升序排序。就变成了…

京东h5st 4.8逆向

最开始扒的时候版本号还是4.1&#xff0c;现在已经到了4.8了&#xff0c;原来的AES也没有了&#xff0c;现在都是魔改的加密方法&#xff0c;还整成了vmp。跟了一下整个流程&#xff0c;和原来的流程大差不差&#xff0c;h5st变长了&#xff0c;一共分9部分。简单走一下流程。 …

玩具车检测系统源码分享

玩具车检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

web基础—dvwa靶场(十二)JavaScript Attacks

JavaScript Attacks (前端攻击) 本章节中的攻击旨在帮助您了解如何在浏览器中使用 JavaScript 以及如何对其进行操作&#xff0c;攻击可以通过分析网络流量来实现&#xff0c;但这不是本章节的重点而且可能要困难得多。 只需提交单词 “success” 即可攻击成功&#xff0c;显然…

编写程序,在一行上显示1-5数字,每个相邻的数字要求用空格进行分开

目录 前言 一、一行输出&#xff08;使用一个System语句输出&#xff09; 二、多行输出&#xff08;使用多&#xff08;N&#xff09;个System语句输出&#xff09; 三、循环输出&#xff08;使用for语句循环在通过System语句输出&#xff09; 四、完整代码 前言 1.本文所…

图神经网络池化方法

图神经网络池化方法 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 图神经网络池化方法前言一、扁平图池化二、分层图池化1.节点聚类池化2.节点丢弃池化 参考文献 前言 图池化操作根据其池化策略的差异&#xff…

windows C++-并行编程-并行算法(四)- 并行排序

并行模式库 (PPL) 提供了对数据集合并行地执行工作的算法。这些算法类似于 C 标准库提供的算法。并行算法由并发运行时中的现有功能组成。 PPL 提供三种排序算法&#xff1a;concurrency::parallel_sort、concurrency::parallel_buffered_sort 和 concurrency::parallel_radix…

志邦家居CIO吴俊涛谈转型:天润融通如何赋能家居行业未来

根据国家统计局、住建部等各部门综合数据显示&#xff0c;2024年国内泛家居全渠道销售额在预计将超过4.7万亿元&#xff0c;并且在存量房需求释放与智能家居品类创新的推动下&#xff0c;预计2027年将突破5.3万亿元&#xff0c;展现出强劲的增长弹性。 然而&#xff0c;家居行…

【Mysql】为modified_time和created_time设置默认值

建立表SQL&#xff1a; CREATE TABLE your_table_name (id int(11) NOT NULL AUTO_INCREMENT,/* 其他字段 */created_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建日期,modified_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 修改…

如果 Linux 这么好,为什么没有更多的人使用它呢?

原文&#xff1a;DHH - 2024.09.02 几周前&#xff0c;我在推特上看到一个问题&#xff1a;“如果 Linux 这么好&#xff0c;为什么没有更多的人使用它呢&#xff1f;” 这是一个很合理的问题&#xff01;在你仔细考虑之前&#xff0c;直觉上这是正确的。Linux 甚至是免费的&a…

neo4j关系的创建删除 图的删除

关系的创建和删除 关系创建 CREATE (:Person {name:"jack"})-[:LOVE]->(:Person {name:"Rose"})已有这个关系时&#xff0c;merge不起效果 MERGE (:Person {name:"Jack" })-[:LOVE]->(:Person {name:"Rose"})关系兼顾节点和关…

10_Python流程控制_循环

循环 循环是控制程序重复执行特定代码块的关键结构。Python提供了几种不同的循环结构&#xff0c;以满足不同的编程需求。 While循环 while 循环会重复执行一个代码块&#xff0c;只要指定的条件为真。 适用情况&#xff1a;不清楚具体的循环次数&#xff0c;或者当条件一直…

“科学突破奖”获得者连续两篇Nature,成功绘制人类主要激酶底物特异性图谱

激酶研究进展 近期Nature期刊发表关于酪氨酸激酶的研究文章。这是威尔康奈尔医学癌症中心Jared L. Johnson和Lewis C. Cantley团队自2023年成功绘制丝/苏氨酸激酶底物特异性图谱后&#xff0c;时隔一年后再次成功绘制酪氨酸激酶底物特异性图谱&#xff0c;为理解激酶在信号传导…

MyBatis 分批次执行(新增,修改,删除)

import com.google.common.collect.Lists;import java.util.Iterator; import java.util.List; import java.util.function.Consumer;/*** Description mybatis分批插入数据使用* Author WangKun* Date 2024/9/19 11:20* Version*/ public class MyBatisSqlUtils {/*** param d…

Linux进阶命令-scp

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 经过上一章Linux日志的讲解&#xff0c;我们对Linux系统自带的日志服务已经有了一些了解。我们接下来将讲解一些进阶命令&am…

快速编写一款python漏洞批量检测工具

一、前言 以下列检测脚本示列&#xff1a; import requestsimport urllib3import re,string,randomfrom urllib.parse import urljoinimport argparseimport timeimport sslssl._create_default_https_context ssl._create_unverified_contexturllib3.disable_warnings(urllib…

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

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

usemeno和usecallback区别及使用场景

1. useMemo 用途: useMemo 用于缓存计算结果。它接受一个函数和依赖项数组&#xff0c;只有当依赖项发生变化时&#xff0c;才会重新计算该函数的返回值。否则&#xff0c;它会返回缓存的值。 返回值: useMemo 返回的是函数执行后的结果。 使用场景: 当一个计算量大的函数在每…