Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_init 函数
ngx_os_init
声明在 src/os/unix/ngx_os.h
ngx_int_t ngx_os_init(ngx_log_t *log);
定义在 src\os\unix\ngx_posix_init.c
ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) != NGX_OK) {return NGX_ERROR;} #endifif (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}ngx_pagesize = getpagesize();ngx_cacheline_size = NGX_CPU_CACHE_LINE;for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }#if (NGX_HAVE_SC_NPROCESSORS_ONLN)if (ngx_ncpu == 0) {ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);} #endifif (ngx_ncpu < 1) {ngx_ncpu = 1;}#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);if (size > 0) {ngx_cacheline_size = size;} #endifngx_cpuinfo();if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {ngx_log_error(NGX_LOG_ALERT, log, errno,"getrlimit(RLIMIT_NOFILE) failed");return NGX_ERROR;}ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)ngx_inherited_nonblocking = 1; #elsengx_inherited_nonblocking = 0; #endiftp = ngx_timeofday();srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);return NGX_OK; }初始化操作系统相关的参数和配置,为 Nginx 的运行环境做好准备
代码逻辑分析
操作系统特定初始化 :
- 如果定义了
NGX_HAVE_OS_SPECIFIC_INIT,调用ngx_os_specific_init进行特定操作系统的初始化。- 如果失败,直接返回错误。
进程标题初始化 :
- 调用
ngx_init_setproctitle初始化进程标题设置功能。- 如果失败,直接返回错误。
系统参数初始化 :
- 获取系统页面大小(
getpagesize)并计算页面大小的对数(ngx_pagesize_shift)。- 初始化 CPU 缓存行大小(
ngx_cacheline_size),如果支持_SC_LEVEL1_DCACHE_LINESIZE,则从系统获取缓存行大小。CPU 核心数初始化 :
- 如果定义了
NGX_HAVE_SC_NPROCESSORS_ONLN,通过sysconf(_SC_NPROCESSORS_ONLN)获取 CPU 核心数。- 如果核心数小于 1,则默认设置为 1。
CPU 信息初始化 :
- 调用
ngx_cpuinfo获取 CPU 相关信息。文件描述符限制 :
- 使用
getrlimit获取当前进程的最大文件描述符限制。- 如果获取失败,记录错误日志并返回错误。
非阻塞套接字标志 :
- 根据是否支持
NGX_HAVE_INHERITED_NONBLOCK或NGX_HAVE_ACCEPT4,设置ngx_inherited_nonblocking标志。随机数种子初始化 :
- 使用当前进程 ID、时间戳(秒和毫秒)生成随机数种子。
返回成功 :
- 如果所有初始化步骤都成功,返回
NGX_OK。
详解
函数签名
ngx_int_t ngx_os_init(ngx_log_t *log)
参数:
ngx_log_t *log:日志对象指针,用于记录错误或调试信息。返回值:
ngx_int_tNginx 自定义的一个整数类型
NGX_OK:表示函数执行成功,所有初始化步骤均顺利完成。NGX_ERROR:表示函数执行失败,某些初始化步骤未能完成
局部变量声明
ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif
tp:指向时间结构体ngx_time_t的指针,用于获取当前时间。n:无符号整数,用于计算页面大小的对数。size(条件编译):长整型变量,用于存储 CPU 缓存行大小。
NGX_HAVE_LEVEL1_DCACHE_LINESIZE是 Nginx 源码中的一个宏,用于指示当前系统是否支持获取 CPU 一级缓存(L1 Data Cache)的缓存行大小
定义在 objs/ngx_auto_config.h 中
#ifndef NGX_HAVE_LEVEL1_DCACHE_LINESIZE #define NGX_HAVE_LEVEL1_DCACHE_LINESIZE 1 #endif
操作系统特定初始化
#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) != NGX_OK) {return NGX_ERROR;} #endif
NGX_HAVE_OS_SPECIFIC_INIT:- 这是一个宏,表示是否需要执行特定操作系统的初始化逻辑。
ngx_os_specific_init:- 调用特定于操作系统的初始化函数。如果初始化失败,直接返回
NGX_ERROR。- 意图 :通过条件编译,支持不同操作系统的定制化初始化逻辑,增强跨平台兼容性。
NGX_HAVE_OS_SPECIFIC_INIT
定义在 src\os\unix\ngx_linux_config.h#define NGX_HAVE_OS_SPECIFIC_INIT 1
使用 gcc -E 处理条件编译后,确认一下我当前 Ubuntu 环境下的实际情况
gcc -E src/os/unix/ngx_posix_init.c \-I src/core \-I src/event \-I src/event/modules \-I src/os/unix \-I objs \> ngx_posix_init_preprocessed.c在输出文件中查找 ngx_os_init 函数
ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n;long size;if (ngx_os_specific_init(log) != 0) {return -1;}if (ngx_init_setproctitle(log) != 0) {return -1;}ngx_pagesize = getpagesize();ngx_cacheline_size = 64;for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { }if (ngx_ncpu == 0) {ngx_ncpu = sysconf( # 60 "src/os/unix/ngx_posix_init.c" 3 4_SC_NPROCESSORS_ONLN # 60 "src/os/unix/ngx_posix_init.c");}if (ngx_ncpu < 1) {ngx_ncpu = 1;}size = sysconf( # 69 "src/os/unix/ngx_posix_init.c" 3 4_SC_LEVEL1_DCACHE_LINESIZE # 69 "src/os/unix/ngx_posix_init.c");if (size > 0) {ngx_cacheline_size = size;}ngx_cpuinfo();if (getrlimit( # 77 "src/os/unix/ngx_posix_init.c" 3 4RLIMIT_NOFILE # 77 "src/os/unix/ngx_posix_init.c", &rlmt) == -1) {if ((log)->log_level >= 2) ngx_log_error_core(2, log, # 78 "src/os/unix/ngx_posix_init.c" 3 4(*__errno_location ()) # 78 "src/os/unix/ngx_posix_init.c", "getrlimit(RLIMIT_NOFILE) failed");return -1;}ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;ngx_inherited_nonblocking = 1;tp = (ngx_time_t *) ngx_cached_time;srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);return 0; }
ngx_os_specific_init
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_specific_init函数-CSDN博客
进程标题初始化
if (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}
ngx_init_setproctitle:初始化进程标题设置功能,允许修改进程的命令行标题(如ps命令中显示的内容)- 意图 :方便管理员通过工具查看 Nginx 进程的状态(如主进程、工作进程等)
ngx_init_setproctitle
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_setproctitle函数-CSDN博客
系统页面大小初始化
ngx_pagesize = getpagesize();ngx_cacheline_size = NGX_CPU_CACHE_LINE;for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
getpagesize():获取系统页面大小(单位为字节),例如 4KB。ngx_pagesize:全局变量,存储页面大小。ngx_cacheline_size:全局变量,存储 CPU 缓存行大小,默认值为NGX_CPU_CACHE_LINE。for循环 :计算页面大小的对数(ngx_pagesize_shift),即页面大小是 2 的多少次幂。例如,4KB 的页面大小对应ngx_pagesize_shift = 12。- 意图 :页面大小和缓存行大小是性能优化的重要参数,直接影响内存分配和 CPU 缓存效率。
getpagesize在 C 语言中,
getpagesize()函数用于获取系统内存页的大小(以字节为单位)函数原型
int getpagesize(void);返回值
- 返回值是一个整数,表示系统内存页的大小(以字节为单位)
- 例如,在许多现代系统上,返回值通常是 4096 字节(即 4KB)
需要包含以下头文件:
#include <unistd.h>
NGX_CPU_CACHE_LINE
定义在 objs/ngx_auto_config.h
#ifndef NGX_CPU_CACHE_LINE #define NGX_CPU_CACHE_LINE 64 #endif
CPU 核心数初始化
#if (NGX_HAVE_SC_NPROCESSORS_ONLN)if (ngx_ncpu == 0) {ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);} #endifif (ngx_ncpu < 1) {ngx_ncpu = 1;}
sysconf(_SC_NPROCESSORS_ONLN):获取当前系统在线的 CPU 核心数。ngx_ncpu:全局变量,存储 CPU 核心数。- 默认值处理 :如果核心数小于 1,则设置为 1(防止异常情况)。
- 设计意图 :根据 CPU 核心数动态调整工作线程的数量,充分利用多核优势。
NGX_HAVE_SC_NPROCESSORS_ONLN
定义在 objs/ngx_auto_config.h
#ifndef NGX_HAVE_SC_NPROCESSORS_ONLN #define NGX_HAVE_SC_NPROCESSORS_ONLN 1 #endif用于指示当前系统是否支持通过
sysconf(_SC_NPROCESSORS_ONLN)获取在线 CPU 核心数。它的定义与否取决于目标操作系统和硬件平台的特性不同的操作系统对
sysconf(_SC_NPROCESSORS_ONLN)的支持情况不同:
- Linux :完全支持
sysconf(_SC_NPROCESSORS_ONLN),因此该宏通常会被定义。- Windows :Windows 不支持 POSIX 标准的
sysconf函数,因此该宏不会被定义
sysconf
函数原型
long sysconf(int name);
返回值 :
- 成功时,返回与
name参数对应的系统配置值。- 如果发生错误(例如参数无效或功能不支持),返回
-1。参数 :
name:指定要查询的系统配置选项。它是一个常量,表示不同的系统属性。
_SC_NPROCESSORS_ONLN是其中一个常量,表示系统中当前在线的 CPU 核心数。
CPU 缓存行大小初始化
#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);if (size > 0) {ngx_cacheline_size = size;} #endif
sysconf(_SC_LEVEL1_DCACHE_LINESIZE):获取一级缓存行大小。- 更新
ngx_cacheline_size:如果获取到的值有效,则更新全局变量。- 意图 :缓存行大小影响内存对齐和性能优化,动态获取可以适配不同的硬件架构。
NGX_HAVE_LEVEL1_DCACHE_LINESIZE
定义在 objs/ngx_auto_config.h
#ifndef NGX_HAVE_LEVEL1_DCACHE_LINESIZE #define NGX_HAVE_LEVEL1_DCACHE_LINESIZE 1 #endif
CPU 信息初始化
ngx_cpuinfo();
ngx_cpuinfo:获取 CPU 的详细信息(如型号、特性等),并存储在全局变量中。
ngx_cpuinfoUbuntu 下 nginx-1.24.0 源码分析 - ngx_cpuinfo 函数-CSDN博客
文件描述符限制初始化
if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {ngx_log_error(NGX_LOG_ALERT, log, errno,"getrlimit(RLIMIT_NOFILE) failed");return NGX_ERROR;}ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;
getrlimit:获取当前进程的最大文件描述符限制。rlmt:存储限制值的结构体。ngx_max_sockets:全局变量,存储最大文件描述符数量。- 错误处理 :如果获取失败,记录错误日志并返回
NGX_ERROR。- 意图 :文件描述符限制决定了 Nginx 能同时处理的最大连接数,合理设置可以避免资源耗尽。
getrlimit
getrlimit是一个 POSIX 标准函数,用于获取当前进程的资源限制。它允许程序查询操作系统对某种资源的硬限制(hard limit)和软限制(soft limit)
函数原型
int getrlimit(int resource, struct rlimit *rlim);
返回值 :
- 成功时返回
0。- 失败时返回
-1,并设置errno表示错误原因。(1)
resource参数
类型 :
int含义 :指定要查询的资源类型。
常用值 :
RLIMIT_NOFILE:表示文件描述符的最大数量(Number of Open Files)。- 其他可能的值包括:
RLIMIT_CPU:CPU 时间限制。RLIMIT_DATA:数据段大小限制。RLIMIT_STACK:栈大小限制。意图 :
- 在这里,
RLIMIT_NOFILE被传递给getrlimit,表示我们关心的是文件描述符的数量限制。(2)
rlim参数
- 类型 :
struct rlimit *- 含义 :指向一个
rlimit结构体的指针,用于存储查询结果。
rlimit结构体定义struct rlimit {rlim_t rlim_cur; // 软限制(Soft Limit)rlim_t rlim_max; // 硬限制(Hard Limit) };
rlim_cur:
- 当前生效的限制值(软限制)。
- 进程可以动态调整软限制,但不能超过硬限制。
rlim_max:
- 最大允许的限制值(硬限制)。
- 只有超级用户(root)才能修改硬限制。
意图
获取文件描述符限制
- 文件描述符是操作系统用于管理打开文件、套接字等资源的抽象句柄。
- 每个进程都有一个文件描述符表,其大小由
RLIMIT_NOFILE决定。- 通过调用
getrlimit(RLIMIT_NOFILE, &rlmt),Nginx 获取当前进程的文件描述符限制:
rlmt.rlim_cur:当前允许的最大文件描述符数量(软限制)。rlmt.rlim_max:理论上允许的最大文件描述符数量(硬限制)。
非阻塞套接字标志初始化
#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)ngx_inherited_nonblocking = 1; #elsengx_inherited_nonblocking = 0; #endif
ngx_inherited_nonblocking:全局变量,指示是否支持继承非阻塞套接字。- 条件编译 :根据是否支持
NGX_HAVE_INHERITED_NONBLOCK或NGX_HAVE_ACCEPT4设置标志。- 意图 :非阻塞套接字是高并发网络编程的基础,确保套接字行为一致。
NGX_HAVE_INHERITED_NONBLOCK
含义 :
- 表示当前系统是否支持继承非阻塞套接字(Inherited Non-blocking Sockets)。
- 如果定义了该宏,则表示系统允许父进程创建的套接字在子进程中保持非阻塞状态。
背景 :
- 在传统的网络编程中,套接字的阻塞或非阻塞状态是由每个进程独立管理的。
- 如果系统支持继承非阻塞套接字,则父进程设置的非阻塞状态可以直接被子进程继承,而无需额外的系统调用。
优点 :
- 减少了系统调用的开销,提高了性能。
- 简化了多进程模型中的套接字管理逻辑。
NGX_HAVE_ACCEPT4
含义 :
- 表示当前系统是否支持
accept4系统调用。accept4是 Linux 内核 2.6.28 引入的一个扩展版本的accept系统调用,允许在接收新连接时直接设置套接字选项(如非阻塞模式)。背景 :
- 传统的
accept系统调用仅返回一个新的套接字文件描述符,但无法直接设置套接字选项。- 使用
accept4可以在接收连接的同时设置套接字为非阻塞模式或其他选项,从而减少额外的系统调用。优点 :
- 提高了性能,减少了系统调用次数。
- 简化了代码逻辑,避免了在
accept后手动调用fcntl或其他函数来设置套接字选项。
随机数种子初始化
tp = ngx_timeofday();srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
ngx_timeofday:获取当前时间戳。srandom:设置随机数种子。- 种子生成公式 :
(进程 ID << 16) ^ 当前秒数 ^ 当前毫秒数。- 意图 :随机数种子用于生成唯一的随机数序列,避免每次运行时生成相同的随机数。
ngx_timeofday定义在 src/core/ngx_times.h
#define ngx_timeofday() (ngx_time_t *) ngx_cached_time
srandom:
srandom是标准库函数,用于设置随机数生成器的种子。种子值决定了随机数序列的初始状态。如果种子值不同,生成的随机数序列也会不同。
返回成功
return NGX_OK;
相关文章:
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_init 函数
ngx_os_init 声明在 src/os/unix/ngx_os.h ngx_int_t ngx_os_init(ngx_log_t *log); 定义在 src\os\unix\ngx_posix_init.c ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif#if (NGX…...
【Python项目】基于Python的语音数据及标注核对审核系统
【Python项目】基于Python的语音数据及标注核对审核系统 技术简介: 采用Python技术、MySQL数据库、Django框架等实现。 系统简介: 语音数据及标注核对审核系统是一个基于B/S架构的语音数据处理平台,旨在通过自动化的方式对语音数据进行标…...
深入解析BFS算法:C++实现无权图最短路径的高效解决方案
在无权图中,广度优先搜索(BFS)是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节,并给出C代码示例: 目录 一、核心原理 二、算法步骤 三、C实现关键点 1. 数据结构 2. 边界检查 3. 路径回溯…...
LeetCode刷题---二分查找---441
排列硬币 441. 排列硬币 - 力扣(LeetCode) 题目 你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。 给你一个数字 n ,计算…...
Unity结合Vuforia虚拟按键实现AR机械仿真动画效果
零、最终效果 待上传 一、资源准备 1、Vuforia Vuforia版本不能高于10.17.4(往上的版本虚拟按键功能被删除) 2、Unity Unity版本必须要高于2022.3.x,不然使用Vuforia插件时会出现bug 二、主要内容 1、添加虚拟按钮 2、为虚拟按钮设置…...
网络安全 linux学习计划 linux网络安全精要
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 2.使用命令行 文件系统层次标准(FHS)是一个文件和目录在Unix和Linux操作系统上面应该如何存储的定义。 /bin 重要的二进制可执行程序/bo…...
深度解析2025最新微服务版本特性
当程序猿张三在凌晨三点对着满屏报错日志抓狂时,他绝对想不到2025年的微服务架构已经进化成了会哄睡的技术保姆。这年头要是谁家系统还像俄罗斯套娃般环环相扣,出门都不好意思跟同行打招呼。且看这群代码世界的乐高大师们,今年又给我们整了哪…...
世界棒球经典赛(World Baseball Classic)·棒球1号位
世界棒球经典赛(World Baseball Classic)是一项由美国职棒大联盟(MLB)和国际棒球总会(IBAF,现更名为世界棒垒球联盟WBSC)共同主办的国际棒球赛事。该赛事吸引了来自世界各地的顶尖棒球队伍参与&…...
为AI聊天工具添加一个知识系统 之115 详细设计之56 知识表征 之2
本文要点 要点 知识表征的顶级范畴中最好是先将九个原语primitive T, ⊥, Independent, Relative, Mediating, Physical, Abstract, Continuant,和 Occurrent 进行分组(分成2大组 和 4个小组)并写出它们的满足公司,然后将它们和三种设计&am…...
rust 实例化动态对象
在功能开发中,动态创建或获取某个对象的情况很多。在前端JS开发中,可以使用工厂函数,通过给定的类型标识创建不同的对象实例;还可以通过对象映射来实现动态创建对象。 在Rust中,我们也可以使用这两种方式去创建对象实…...
支持向量机 (Support Vector Machine, SVM)
支持向量机 (Support Vector Machine, SVM) 支持向量机(SVM)是一种广泛应用于分类、回归分析以及异常检测的监督学习算法。它基于结构风险最小化(Structural Risk Minimization,SRM)原则,通过寻找一个最优…...
C#初级教程(1)——C# 与.NET 框架:探索微软平台编程的强大组合
图片来源: https://www.lvhang.site/docs/dotnettimeline 即梦AI - 一站式AI创作平台 一、历史发展脉络 在早期的微软平台编程中,常用的编程语言有 Visual Basic、C、C。到了 20 世纪 90 年代末,Win32 API、MFC(Microsoft Found…...
Mac m1 连接公司内网
1、创建VPN 1、在系统偏好设置 2、选择网络 3、进行添加 2、添加设置 1、选择VPN 2、类型选择L2TP/IPSec 3、填写服务器IP和账号 4、点击认证设置-填写密码 。然后应用 3、进行特殊配置 网上说苹果系统的问题。 1、创建命令 sudo vim /etc/ppp/options 2、添加内容-主要别…...
C++:类与对象,定义类和构造函数
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; //如何让定义一个类 // 封装 // 1、将数据和方法定义到一起。 // 2、把想给你看的数据给你看,不想给你看的封装起来。 通过访问限定符来实现 class Stack { public: //1.成…...
杨校老师课堂之信息学奥赛结构体操作使用经典题集锦汇总
C基础:结构体数组综合训练 员工信息处理系统题目描述输入描述输出描述解题思路参考代码 员工信息处理系统 题目描述 在一家企业中,员工信息的准确性和时效性是日常人事管理工作的关键。由于企业员工数量众多,手动统计与更新员工信息不仅耗费大量时间&a…...
8. Flink-CDC
1. Flink-CDC的介绍 Flink-cdc主要是用来同步数据库中的数据,它的主要优势在于基于Flink框架直接用Flink Stream Api 或Flink SQL 直接编程,不需要引入第三方组件 2.Flink-CDC的使用 Flink-cdc在使用上需要注意的点 注意Flink-cdc在2.1版本之前需要导…...
Windows 权限结构和原理:深入浅出
一、什么是权限? 权限,是指在操作系统或应用程序中,某个对象(如用户、程序、设备等)对特定资源的可操作范围。具体来说,权限控制了一个主体(通常是用户或应用程序)对某个资源&#…...
Nginx环境安装
一、官网地址 Nginx官网:http://nginx.org/ Nginx中文网:https://nginx.p2hp.com/ 二、Nginx版本 mainline version 开发版本stableversion 稳定版本legacy version 历史版本 三、Windows系统安装Nginx 第一步:选择Windows版本,…...
Spring AI + Ollama 实现调用DeepSeek-R1模型API
一、前言 随着人工智能技术的飞速发展,大语言模型(LLM)在各个领域的应用越来越广泛。DeepSeek 作为一款备受瞩目的国产大语言模型,凭借其强大的自然语言处理能力和丰富的知识储备,迅速成为业界关注的焦点。无论是文本生…...
android系统SystemServer进程启动流程分析
目录 一,SystemServer整体框架 二,SystemServer启动源码分析 2.1,重要的概念 2.2,启动入口 2.3,创建对应进程的binder 三,binder驱动和binder线程池 四,SystemServer真正启动方法 4.1 SystemServer main方法里面主要做了几件事情 1)创建SystemServiceManager管理所有的…...
【雅思博客06】Daily Life
对话 A: Honey, the house is such a mess! I need you to help me tidy up a bit. My boss and her husband are coming over for dinner, and the house needs to be spotless! B: I’m in the middle of something right now. I’ll be there in a second. A: This can’t …...
Oracle 深入理解Lock和Latch ,解析访问数据块全流程
Oracle 锁机制介绍 根据保护对象的不同,单实例Oracle数据库锁可以分为以下几大类: DML lock(data locks,数据锁):用于保护数据的完整性; DDL lock(dictionary locks,字典…...
19、《Springboot+MongoDB整合:玩转文档型数据库》
SpringbootMongoDB整合:玩转文档型数据库 摘要:本文全面讲解Spring Boot与MongoDB的整合实践,涵盖环境搭建、CRUD操作、聚合查询、事务管理、性能优化等核心内容。通过15个典型代码示例,演示如何高效操作文档数据库,深…...
如何基于transformers库通过训练Qwen/DeepSeek模型的传统分类能力实现文本分类任务
文章目录 模型与环境准备文档分析源码解读模型训练及推理方式进阶:CPU与显存的切换进阶:多卡数据并行训练🔑 DDP 训练过程核心步骤🚫 DDP 不适用于模型并行⚖️ DDP vs. Model Parallelism⚙️ 解决大模型训练的推荐方法🎉进入大模型应用与实战专栏 | 🚀查看更多专栏…...
Unity中一个节点实现植物动态(Shader)
1 . 核心思路就操作顶点作往复运动; 核心代码: half stage1 dot(positionOS, float3(0, 1, 0)) * _Strength; half stage2 sin(dot(positionOS, float3(1, 0, 0)) * _Strength _Time.y * _Speed); half stage3 stage1 * stage2 * float3(0.001,…...
PrimeTime:工具简介
相关阅读 PrimeTimehttps://blog.csdn.net/weixin_45791458/category_12900271.html?spm1001.2014.3001.5482 PrimeTime是PrimeTime Suite中的一个工具,能够执行全芯片级、门级的静态时序分析,这是芯片设计和分析流程中的一个关键部分。该工具通过检查…...
FFmpeg+WebSocket+JsMpeg实时视频流实现方案
之前写的使用FFmpeg Nginx HLS流媒体播放方案,适合对实时性要求不高的需求,存在延迟,FFmpeg需要将视频流存储到本地文件,而本次方案FFmpeg不需要将视频流存储到本地文件,而是直接将转换后的视频流(如MJPE…...
《论系统需求分析方法》写作心得 - 系统分析师
系统需求分析方法论述 一、项目概述及本人职责 本人曾参与一项企业级客户关系管理系统(CRM)的开发项目,担任系统分析师的角色。该项目旨在为企业提供一个集客户信息管理、销售过程跟踪、客户服务支持于一体的综合管理平台,以提升…...
DuodooBMS源码解读之 mrp_management模块
制造管理扩展模块用户使用手册 一、模块概述 本扩展模块是基于 Odoo 18 开发的制造管理模块,主要为用户提供了更为强大和细致的制造管理功能。该模块添加了数量验证功能,即当一步工序未完成时,开始下一步工序,则下一步工序的生产…...
rust笔记8-Deref与隐式解引用强制转换
Rust 的智能指针和 Deref Trait 是 Rust 中非常重要的概念,它们使得 Rust 的引用和指针操作更加灵活和安全。下面我们将深入介绍 Deref Trait、Deref 与 &、* 运算符的关系,以及 Rust 的隐式解引用强制转换(Deref Coercion)。 1. 智能指针与 Deref Trait 智能指针(如…...
