Skynet 中 snlua 服务启动整体流程分析
前言:
在 Skynet 中,Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里,而能够将 Lua 环境嵌入到 Skynet 框架下,并与 Skynet 消息调度机制完美结合,正是 snlua
服务所承担的核心功能。
本文将着重分析
snlua
服务的核心实现,包括其初始化过程、协程扩展(Profile)、内存管理,以及如何与 Skynet 主循环交互等细节,帮助你在阅读 Skynet 代码或自定义服务时更好地理解这一部分的原理与运作。
1. 整体概览
snlua
服务是 Skynet 提供的一个 C 语言服务(又称为 service ),它的主要职责是:
- 创建并管理 Lua 虚拟机:调用
lua_newstate
建立独立的 Lua 环境。 - 接收并处理来自 Skynet 的消息:通过设置回调函数
skynet_callback
,让 Lua 脚本处理游戏或业务逻辑的各种消息。 - 扩展 Lua 协程的性能统计(Profile):覆盖
coroutine.resume
和coroutine.wrap
,并使用钩子(hook)来计量协程执行的耗时。 - 内存使用监控与限制:自定义分配器
lalloc
,实现对 Lua 内存占用的统计与警告甚至限制。 - 执行 Lua 启动脚本:如
lualoader.lua
,并从外部接收启动参数,将其传递给 Lua 环境初始化服务逻辑。
通过 snlua
服务,Skynet 可以在 C 层面精准控制和监控 Lua 层的一些关键点(如内存、协程)。这使得 Skynet 保持了高性能的特性,且拥有动态脚本语言的灵活性。
2. 核心数据结构
在 snlua.c
中,最核心的结构体是:
struct snlua {lua_State * L; // 该服务所属的 Lua VM 主线程struct skynet_context * ctx; // Skynet 服务上下文size_t mem; // 当前 Lua VM 内存总占用size_t mem_report; // 触发内存预警的阈值size_t mem_limit; // 内存上限,如果 mem 超过此值,分配器将返回 NULLlua_State * activeL; // 当前处于活跃状态的协程ATOM_INT trap; // 用于处理 signal_hook 的标志
};
L
:当前服务对应的 Lua 主线程(Lua VM)。ctx
:Skynet 中表示一个服务的上下文,用于在 C 层与 Skynet 通信。mem
:当前分配的 Lua 内存总大小。mem_report
:当内存超出该值时,会触发一次警告日志,并将此值翻倍。mem_limit
:Lua 内存分配的上限,若超出则直接返回 NULL 并引发错误。activeL
:当前执行的协程,配合信号机制进行调试或中断操作。trap
:一个原子变量,处理调试信号(signal_hook)的标志位。
3. 初始化过程
3.1 创建并初始化 snlua
struct snlua * snlua_create(void) {struct snlua * l = skynet_malloc(sizeof(*l));memset(l,0,sizeof(*l));l->mem_report = MEMORY_WARNING_REPORT; // 默认32M触发报警l->mem_limit = 0; // 默认为0,即无限制l->L = lua_newstate(lalloc, l); // 创建独立的 Lua VM,并使用自定义分配器l->activeL = NULL;ATOM_INIT(&l->trap , 0);return l;
}
这里做了几件事:
- 动态分配
snlua
结构体,并初始化所有字段。 l->mem_report
默认 32M,用于记录内存使用量到达 32M 时进行一次报警,并将阈值翻倍。- 调用
lua_newstate
创建新的 Lua VM,分配器采用自定义的lalloc
用于内存统计。 - 初始化
trap
原子变量为0
,表示当前没有任何调试请求。
3.2 服务启动
当 Skynet 创建一个 snlua
服务时,会指定一个启动函数 launch_cb
作为回调:
int snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {// 将 args 的内容复制一份,随后发送给自己的服务句柄// 由 launch_cb 来进行后续处理skynet_callback(ctx, l , launch_cb);...skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz);return 0;
}
skynet_callback(ctx, l, launch_cb)
:当收到第一个消息时,launch_cb
会被调用。snlua_init
将传入的args
数据打包后再以消息方式发送给自己,从而触发launch_cb
。
在 launch_cb
中,执行真正的初始化函数 init_cb
:
static int launch_cb(struct skynet_context * context, void *ud, int type, int session,uint32_t source , const void * msg, size_t sz) {struct snlua *l = ud;skynet_callback(context, NULL, NULL);int err = init_cb(l, context, msg, sz);if (err) {skynet_command(context, "EXIT", NULL);}return 0;
}
此时将回调置空,保证后续消息交给 Lua 层处理。若初始化失败,则发送退出命令。
3.3 init_cb
:Lua 环境设置与脚本加载
static int init_cb(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {// 1. 绑定 luaL_openlibs, 初始化标准库和 profile 扩展// 2. 设置 Lua 环境变量 (LUA_PATH, LUA_CPATH, LUA_SERVICE 等)// 3. 加载并执行 loader.lua// 4. 处理内存限制...return 0;
}
其中几个关键点:
-
注册标准库与 profile
调用luaL_openlibs(L)
加载基础标准库,同时调用luaL_requiref(L, "skynet.profile", init_profile, 0)
引入了自定义的skynet.profile
模块,以实现对 Lua 协程的耗时统计。 -
覆盖
coroutine.resume
、coroutine.wrap
Skynet 会将resume
、wrap
替换为自己封装的函数,从而统计协程的运行时长。 -
设置全局变量
如LUA_PATH
,LUA_CPATH
,LUA_SERVICE
,LUA_PRELOAD
,方便在 Lua 中通过相应的全局变量查找脚本或动态库。 -
加载
loader.lua
默认路径是./lualib/loader.lua
,这是 Skynet 启动 Lua 服务的核心脚本,其会加载真正的服务主脚本并传入args
作为启动参数。 -
内存限制
如果在 Lua 中设置了memlimit
,则会读取并保存到l->mem_limit
,用于在分配器lalloc
中进行判定。
整个过程完成后,Skynet 中的 Lua 环境就处于可运行状态,后续所有消息将交由 Lua 层脚本来处理。
4. 内存分配器 lalloc
static void * lalloc(void * ud, void *ptr, size_t osize, size_t nsize) {struct snlua *l = ud;size_t mem = l->mem;l->mem += nsize;if (ptr)l->mem -= osize;if (l->mem_limit != 0 && l->mem > l->mem_limit) {// 如果超出限制,分配失败if (ptr == NULL || nsize > osize) {l->mem = mem;return NULL;}}// 报警逻辑if (l->mem > l->mem_report) {l->mem_report *= 2;skynet_error(l->ctx, "Memory warning %.2f M", (float)l->mem / (1024 * 1024));}return skynet_lalloc(ptr, osize, nsize);
}
- 统计:记录当前服务所使用的 Lua VM 内存总量
l->mem
。 - 限制:当
mem_limit != 0
且l->mem > l->mem_limit
,代表超出上限,直接返回NULL
,从而导致 Lua 层内存分配失败并产生错误。 - 报警:若
l->mem
超过l->mem_report
,则打印一条警告日志并将mem_report
翻倍。
这样就保证了每个 snlua
服务可以独立监控内存使用量,防止无限制地占用系统资源。
5. Lua 协程 Profile 机制
Skynet 对 Lua 协程做了扩展,使得我们可以统计每个协程的运行时间。主要思路:
-
替换
coroutine.resume
、coroutine.wrap
在init_profile
函数中,用自定义的函数luaB_coresume
和luaB_cowrap
覆盖原版,以进行耗时计算。 -
开始与结束
用start_time
、total_time
表示协程本次启动时间和累计耗时。每次协程resume
时记下开始时间,协程返回或yield
时累加耗时。 -
结果
在profile.stop()
时,可以拿到协程执行的总耗时,帮助开发者做性能分析。
6. 信号钩子(signal_hook
)
static void signal_hook(lua_State *L, lua_Debug *ar) {...if (ATOM_LOAD(&l->trap)) {ATOM_STORE(&l->trap , 0);luaL_error(L, "signal 0");}
}
- 当
snlua_signal(l, 0)
设置trap
时,Skynet 会在下一次指令执行前(通过lua_sethook
)抛出一个错误,强制中断 Lua 执行。这在调试或终止协程时非常有用。 - 如果
signal = 1
,则仅打印当前内存使用量。
7. snlua
服务启动流程小结
- 创建
snlua
结构,设置自定义分配器与内存统计逻辑。 - 回调函数
launch_cb
中调用init_cb
完成 Lua VM 初始化:- 加载标准库和 Skynet Profile 扩展。
- 设置
LUA_PATH
、LUA_CPATH
、LUA_SERVICE
等全局环境。 - 加载并运行
loader.lua
,启动 Lua 端业务逻辑。
- 后续消息:当 Skynet 将消息派发给这个
snlua
服务时,就会交由 Lua 层的服务脚本来处理,通常通过skynet.dispatch
或skynet.start
设定的回调函数进行处理。
8. 实际使用与自定义
8.1 在 config
中配置
在 Skynet 的 config
文件或启动命令行中,你可以指定服务类型为 snlua
来启动一个 Lua 服务。例如:
# config
thread = 8
bootstrap = "snlua bootstrap"
lua_path = "./lualib/?.lua;./lualib/?/init.lua;"
lua_cpath = "./luaclib/?.so;"
8.2 启动一个 Lua 服务
从命令行或在启动脚本中,可以通过 skynet.newservice("xxx")
或 skynet.uniqueservice("xxx")
来创建一个新的 Lua 服务,底层就是在调度器里分配一个 snlua
服务并调用 snlua_init
,随后再用 launch_cb
加载 xxx.lua
脚本。
8.3 查看内存警告
当某个 Lua 服务的内存使用量超过 MEMORY_WARNING_REPORT
(默认为 32M)时,会打印一条:
[:0000000x] Memory warning 64.00 M
表示该服务已经使用了 64M(后续阈值会翻倍到 128M),便于开发者及时定位内存问题。
9. 结语
snlua
服务作为 Skynet 框架与 Lua 语言结合的关键模块,不仅为 Lua 逻辑层提供了隔离、独立的执行环境,还在 C 层面通过内存管理、协程扩展、信号捕获等手段,为服务器开发者提供了更高的可控性和可调试性。
参考链接
- Skynet 官方仓库
- Skynet Wiki
- Lua 5.4 官方文档
相关文章:
Skynet 中 snlua 服务启动整体流程分析
前言: 在 Skynet 中,Lua 扮演了极其重要的角色。Skynet 大多数业务逻辑都跑在一个个 Lua 服务里,而能够将 Lua 环境嵌入到 Skynet 框架下,并与 Skynet 消息调度机制完美结合,正是 snlua 服务所承担的核心功能。 本文将…...
RWA代币化崛起中的香港机遇:数字金融新枢纽的破局之道
引言:全球资产代币化浪潮中的香港坐标 在2025年全球金融数字化重构的关键节点,RWA(现实世界资产代币化)市场以年均740%的增速重塑价值流动规则。香港凭借独特的政策创新、跨境枢纽优势及庞大的资产储备,正从传统金融中…...
Docker Compose介绍
基本概念 Docker-Compose是Docker官方的开源项目,负责实现对docker容器集群的快速编排。 可以这么理解,docker compose是docker提出的一个工具软件,可以管理多个docker容器组成一个应用,只需要编写一个YAML格式的配置文件docker…...
【LeetCode 题解】算法:15.三数之和
一、问题描述 在 LeetCode 上有这样一道经典的算法题,题目要求给定一个整数数组 nums,找出所有不重复的三元组 [nums[i], nums[j], nums[k]],需要满足以下两个条件: 三个元素的索引互不相同,即 i ! j,i ! …...
springboot使用阿里限流框架-sentinel
当前项目源码 控制台下载 启动bin中的看板服务:账号密码:sentinel/sentinel 官方文档地址 项目引入依赖 <!-- sentinel注解支持 --> <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj<…...
Ubuntu20.04系统安装IsaacSim4.5与IsaacLab环境
Introduction 今天用自己的Ubuntu20.04系统安装最新更新的IsaacSim 4.5 与 最新版的IsaacLab遇到了问题,且这个问题组里师兄之前也遇到了,我的解决方法是从头来过,所及记录一下。 IsaacSim现在支持pip安装,但是Ubuntu20.04的pip…...
【大模型】数字人 EchoMimicV2 的环境配置和使用
一、EchoMimicV2的简单介绍 EchoMimicV2是EchoMimicV1的升级版本,旨在通过音频驱动生成更加自然和流畅的半身人类动画。它能够让用户仅通过简单的音频输入,生成与声音内容相匹配的动画效果,使虚拟人物看起来更加生动。 作者:由蚂蚁…...
导入 Excel 规则批量修改或删除 PDF 文档内容
需要对 PDF 文档内容进行修改的时候,通常我们会需要借助一些专业的工具来帮我们完成。那我们如果需要修改的 PDF 文档较多的时候,有什么方法可以帮我们实现批量操作呢?今天这篇文章就给大家介绍一下当我们需要批量修改多个 PDF 文档的时候&am…...
2.Excel :快速填充和拆分重组
一 案例1:快速填充 电子邮件中包含每个人的人名,现在要提取电子邮件中的姓名到名字列。 方法1:将 Nancy 复制到单元格后,邮件会高亮,然后输入A的时候系统就会知道提取名字了。 补充:如果第三个位置输入错误…...
python tkinter 开发蓍草占卜系统
1. 项目概述 1.1 简介 蓍草占卜是中国传统的占卜方法,用于演算六十四卦。本系统通过现代编程技术,将传统的蓍草占卜方法数字化,提供一个准确、便捷的占卜工具。 蓍草占卜,作为中国古代的一种传统占卜方法,承载着深厚…...
综合小实验之电视机
综合小实验1 一、实验拓扑图 二、实验要求 按照图示配置IP地址;按照图示区域划分配置对应的动态路由协议;在R7上配置dhcp服务器,能够让pc可以获取IP地址;将所有环回⼝宣告进ospf中,将环回⼝7宣告进rip中,…...
全排列|| 分发饼干 摆动序列
1.给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]] 示例 2: 输入:nums [1,2,3] 输出:[[1,2,3…...
【开源宝藏】用 JavaScript 手写一个丝滑的打字机动画效果
你当前项目实现了一个非常丝滑的 打字机文字效果动画,使用的是自定义的 typical.js 脚本。下面我将给出一份逐步拆解的中文教程,帮你或其他初学者快速上手并自定义这个打字效果。 ✨ 最终效果 打开页面后,中央会逐字显示: Hello…...
推荐1款简洁、小巧的实用收音机软件,支持手机和电脑
聊一聊 没想到现在还有人喜欢听广播。 我一直以为听广播必须要用那种小广播机才可以。 原来手机或电脑上也是可以的。 今天给大家分享一款可以在电脑和手机上听广播的软件。 软件介绍 龙卷风收音机 电台广播收音机分电脑和手机两个版本。 电脑端无需安装,下载…...
64. MfgTool烧写工具详解
一、MfgTool工具简介 1、mfgtool是NXP官方做的向I.MX系列烧写系统的软件,运行在windows下。可以烧写uboot.imx、zImage、dtb,rootfs。通过USB烧写。 Mfgtool里面默认存放了NXP官方开发板的系统文件, 2、基本原理 向开发板烧系统分两部分&am…...
3、孪生网络/连体网络(Siamese Network)
目的: 用Siamese Network (孪生网络) 解决Few-shot learning (小样本学习)。 Siamese Network并不是Meta Learning最好的方法, 但是通过学习Siamese Network,非常有助于理解其他Meta Learning算法。 这里介绍了两种方法:Siamese Network (孪生网络)、Trplet Loss Siam…...
前端学习笔记--CSS
HTMLCSSJavaScript 》 结构 表现 交互 如何学习 1.CSS是什么 2.CSS怎么用? 3.CSS选择器(重点,难点) 4.美化网页(文字,阴影,超链接,列表,渐变。。。) 5…...
开个坑记录一下树莓派4B部署yolo的一些问题
问题一:操作系统与内核信息 这个问题困扰了我一天半,下载的时候显示的信息是aar64的系统,但是这并无意味着一个问题,那就是你的操作系统是64位的。需要采用如下的指令查看: getconf LONG_BIT 我在树莓派得出来的操作…...
1.1 结构体与类对象在List中使用区别
一、问题的起源如下的代码是错误的,无法编译通过 struct Point {public int X;public int Y; }List<Point> points new List<Point> { new Point { X 1, Y 2 } }; points[0].X 10; // 编译错误!无法修改副本的字段 二、原因分析 在C#中&…...
详细说明windows系统函数::SetUnhandledExceptionFilter(ExceptionFilter)
::SetUnhandledExceptionFilter(ExceptionFilter); 是 Windows 编程中用于设置顶层未处理异常过滤器的关键 API 调用。它属于 Windows 结构化异常处理(SEH, Structured Exception Handling)机制的一部分,主要用于捕获那些未被程序内部处理的异…...
力扣刷题39. 组合总和
39. 组合总和 - 力扣(LeetCode) 需要定义一个index变量用来记录访问数组的下标,每次递归进行传参,在搜索过程中,因为为了避免重复数据,而且允许一个元素的重复出现,传入index时传入当前遍历的i…...
正弦函数的连续傅里叶变换正弦序列的DTFT
正弦序列 时域 x [ n ] sin ( ω 0 n ) x[n] \sin(\omega_0 n) x[n]sin(ω0n)频域 X ( e j ω ) j π 2 [ δ ( ω − ω 0 ) − δ ( ω ω 0 ) ] X({\rm e}^{{\rm j}\omega}) \frac{{\rm j}\pi}{2} \left[ \delta(\omega - \omega_0) - \delta(\omega \omega_0…...
winstart.wsf 病毒清理大作战
0x00 背景 发现感染了winstart.wsf 病毒如何清理。 0x01 现象 遍历Users下每个目录以及C:\和C:\Windows\Temp 2个目录写入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…...
leetcode 20.有效括号
20. 有效的括号 - 力扣(LeetCode) class Solution:def isValid(self, s: str) -> bool:stack []for i in s :if i in ((,{,[ ):stack.append(i)elif i in () ):# 这种情况是 栈弹出元素为空时候 ,右半部分的括号多出来一些 比如&#x…...
Leetcode刷题笔记1 图论part07
卡码网 53 寻宝 prim算法 prim算法核心就是三步,称为prim三部曲: 第一步,选距离生成树最近节点第二步,最近节点加入生成树第三步,更新非生成树节点到生成树的距离(即更新minDist数组) def p…...
unittest自动化测试实战
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 为什么要学习unittest 按照测试阶段来划分,可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程…...
flask,示例及解释
1) from flask import Flask, render_templateapp Flask(__name__)app.route(/) def index():return render_template(m1index.html)app.route(/get_type) def get_type():return ["语文", "数学"]if __name__ __main__:app.run(host0.0.0.0…...
电机倍频曲线的一些奇异特性-原因分析及应用
这里对感应电机倍频曲线的特征进行了说明,然后将其特性用于电机转差率和工况的测量。先给出可以直接利用的结论: 电机的工况和转差率谱线会体现为5x,7x谱线调制在基频附近。两条调制过携带s信息的谱线距离基频谱线的距离。 与真实转速相对同步转速的频差…...
基于Ebay拍卖网站成交价格的影响因素分析
摘要:近些年来网上拍卖的不断地发展,网上购物慢慢变成了大家普遍接受的购物方式。因此关于网上拍卖的研究日益成为很多人研究的重点。 影响拍卖网站价格的因素很多,但很少有人分得清楚哪些因素才是比较重要的因素,因此对价格因素分析&#x…...
详解图卷积网络
文章目录 GCN/RGCN图卷积网络概述--运作原理**1. GCN(Graph Convolutional Network,图卷积网络)****1.1 核心思想****1.2 公式****1.3 特点****1.4 总结** **2. RGCN(Relational Graph Convolutional Network,关系型图…...
Java 8-17核心特性全景解析之Java9、10
Java 9 核心特性解析 Java 9在2017年9月发布,带来了模块系统等重大变革,是Java平台现代化的重要一步。 模块系统 (Project Jigsaw) 特性概述 模块系统是Java 9最重要的特性,旨在解决Java平台和应用程序的可伸缩性问题,提供更好…...
mysql的学习
关系性数据库需要遵循ACID规则 原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; 一致性: 执行事务前后,数据保持一致,例如转账业务中ÿ…...
leecode 560题
一、题目解析 题目如下->: 这道题的问题是,找到目标值为k的所有连续子串个数,因此最简单最容易想到的就是枚举 两个指针枚举起来确实可以解决,但是时间复杂度极大,达到了O(n^2)的级别 因此这不是我们想要的 二、解题思路 2.1 …...
借壹起航东风,中国工厂出海开启新征程
在经济全球化不断深入的当下,中国工厂正以积极的姿态投身海外市场,渴望在全球商业版图中占据一席之地,绽放独特的光彩。然而,出海之路充满了挑战与艰辛,品牌塑造困难重重、询盘量不稳定、营销成本居高不下等问题&#…...
Joomla教程—查看网站的前台页面与菜单管理(栏目管理)
原文:Joomla 查看网站的前台页面_w3cschool 在本节中,我们将简单介绍一下JOOMLA的前台界面。通过本节的介绍,希望你能对JOOMLA的界面组成有一个大致的了解。 你可以直接在浏览器中输入http://localhost/zmax/ 就会出现我们网站的首页了。也…...
HCIA-WLAN实验
1、划分VLAN,配置IP地址 2、配置AC作为AP的DHCP服务器自动为AP分配IP地址 dhcp enable interface Vlanif100 dhcp select interface 3、建立CAPWAP隧道 capwap source interface vlanif100 4、配置WLAN业务配置,下发至AP ①配置:wlan …...
DNA-PAINT
参考: 【科研教程】NUPACK网页版使用教程 https://www.bilibili.com/video/BV1G94y1W7mN/NUPACK新版网页版教程-模拟部分 https://zhuanlan.zhihu.com/p/678730568NUPACK 4.0 User Guide https://docs.nupack.org/NUPACK网页版使用指南 https://zhuanlan.zhihu.com/p/55024017…...
VS2022的第一个Qt程序——实战《加载并显示图像》
目录 一、UI设计 S1:双击Form Files下.ui文件,进入ui设计界面Qt Designer S2:然后拖动一个Push Button和Label控件到界面 S3:点击信号与槽,然后点击PushButton往外拉一下 S4:松开鼠标进入配置连接界面…...
从概率到梯度:理解分类问题中交叉熵的优越性
分类问题一般使用交叉熵(Cross-Entropy)而不是平方损失(Square Loss)函数1. **概率解释**2. **梯度性质**3. **对错误的惩罚**4. **计算复杂度**5. **总结** 分类问题一般使用交叉熵(Cross-Entropy)而不是平…...
如何选择?Postman vs JMeter 对比介绍
Postman 和 JMeter 作为两款主流测试工具,各有特色。本文将从多个维度详细对比这两款工具最新特性和应用场景。 工具基本介绍 对比项 Postman JMeter 类型 API 开发和测试工具 性能测试工具 开源情况 闭源,提供免费版 开源(Apache L…...
P1182 数列分段 Section II
P1182 数列分段 Section II - 洛谷 题目描述 对于给定的一个长度为 N 的正整数数列 A1∼AN,现要将其分成 M(M≤N)段,并要求每段连续,且每段和的最大值最小。 关于最大值最小: 例如一数列 4 2 4 5 1…...
Thales靶场
信息收集 将靶机改为net模式,开启kali进行扫描,得到靶机ip 对靶机的端口,目录进行扫描,8080端口是 apache tomcat代理 进入8080端口,点击app出现登录窗口,弱口令没试出来,可以爆破登录窗口 查…...
系统思考—看见未来
感谢上海财经大学终身教育学院的持续邀请!每个月,都会带着不同的思维火花,走进财大与学员们一起探索系统思考的奥秘。 这次为宜宾市的干部们带来了一场深刻的学习体验。通过系统思考,帮助大家从整体视角去发现问题、分析问题、解…...
第30周Java分布式入门 ThreadLocal
ThreadLocal 课程笔记 一、章节结构概述 本章主要学习重要的工具类 ThreadLocal。章节分为六大模块: ThreadLocal 的两大使用场景ThreadLocal 所带来的好处ThreadLocal 的主要方法及使用顺序ThreadLocal 原理源码分析使用 ThreadLocal 的注意点和使用规范 从下一…...
Windows 10 LTSC 2019 中文版下载及安装教程(附安装包)
(cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24)涵盖常见疑问和注意事项: cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24 下载链接:https://pan.quark.cn/s/c2c8f3cd18f1 1. 镜像文件来源与合法性 官方渠道&…...
死亡并不是走出生命 而是走出时间
目录 第一章 倒春寒 第二章 悖论与共生 第三章 坍缩与永恒 第四章 在时差里相爱 终章 你从未离开 第一章 倒春寒 2022年春天的扬州东关街,青衣在文昌阁古槐下调试着「时间胶囊」算法。这个能将人类记忆转化为数据流的程序,是他用三年时间对抗渐冻…...
Langchain中的表格解析:RAG 和表格的爱恨情仇
实现 RAG(Retrieval-Augmented Generation)是一个挑战,尤其是在有效解析和理解非结构化文档中的表格时。这在处理扫描文档或图像格式的文档时尤为困难。这些挑战至少包括以下三个方面: 1.表格的“叛逆期”:不准确的解析可能会破坏表格结构: 表格在文档里就像个叛逆的青少…...
STM32F103_LL库+寄存器学习笔记02 - 开启SysTick(滴答定时器)中断
导言 《STM32F103_LL库寄存器学习笔记01 - 梳理CubeMX生成的LL库最小的裸机系统框架》上一章节对CubeMX生成的最小系统框架进行梳理,在此工程的基础上,梳理SysTick(滴答定时器)中断是怎样开启的?为什么SysTick中断会自…...
AI小白的第七天:必要的数学知识(概率)
概率 Probability 1. 概率的定义 概率是一个介于 0 和 1 之间的数,表示某个事件发生的可能性: 0:事件不可能发生。1:事件必然发生。0 到 1 之间:事件发生的可能性大小。 例如,掷一枚公平的硬币…...
SVN常用命令
SVN常用命令 基本操作命令 • 检出代码(Checkout):从SVN服务器获取代码到本地。 svn checkout [svn服务器url] [检出本地的path] 示例: svn checkout svn://47.106.183.193/helloworld ./ • 提交代码(Commit&…...