【Linux系统编程】(三十四)初识进程信号:Linux 软中断的核心奥秘

【Linux系统编程】(三十四)初识进程信号:Linux 软中断的核心奥秘

目录

前言

一、从生活场景理解信号:原来信号这么简单

1.1 快递的故事:完美映射信号处理流程

1.2 生活场景到 Linux 信号的核心结论

二、技术视角:Linux 进程信号的初体验

2.1 第一个实验:Ctrl+C的本质 —— 向前台进程发送 2 号信号SIGINT

代码实现:sig_hello.c

编译运行

2.2 第二个实验:修改信号处理方式 —— 让Ctrl+C不再终止进程

2.2.1 signal函数介绍

2.2.2 代码实现:sig_catch.c

2.2.3 编译运行

2.2.4 实验思考:为什么进程不终止了?

2.3 关键知识点:前台进程与后台进程的信号差异

实战验证:后台进程不接收Ctrl+C信号

三、Linux 信号的核心概念:你必须知道的基础定义

3.1 信号的官方定义

3.2 如何查看 Linux 系统中的所有信号

3.3 信号的三种处理动作

3.3.1 执行默认动作(SIG_DFL)

3.3.2 忽略信号(SIG_IGN)

代码验证:忽略 SIGINT 信号

3.3.3 自定义捕捉(Catch)

代码验证:一个函数处理多个信号

3.4 信号的宏定义

四、信号的异步性:进程控制流程的 “意外插曲”

4.1 什么是信号的异步性

4.2 为什么信号不能立即处理

4.3 信号的处理时机:内核态 → 用户态的切换时刻

五、常见终端信号的实战:除了 Ctrl+C,还有这些操作

5.1 Ctrl+\:SIGQUIT 信号,终止进程并生成 core dump

实战验证:SIGQUIT 信号的默认动作

5.2 Ctrl+Z:SIGTSTP 信号,暂停前台进程

实战验证:SIGTSTP 信号的默认动作

总结


前言

        在 Linux 系统中,进程信号是实现进程间异步通信的核心机制,也是操作系统对进程进行事件通知的重要手段,被称为软中断。无论是我们日常按下Ctrl+C终止进程,还是程序出现段错误、除零异常,背后都是信号在发挥作用。很多 Linux 初学者会觉得信号晦涩难懂,其实它的逻辑和我们生活中的场景高度相似。本文将从生活视角切入,结合实战代码,由浅入深带你认识进程信号,搞懂信号的识别、产生、处理全流程,为后续深入学习信号的保存、捕捉、阻塞打下坚实基础。下面就让我们正式开始吧!

一、从生活场景理解信号:原来信号这么简单

        想要搞懂 Linux 进程信号,不如先从我们身边的小事说起。信号的核心逻辑在生活中随处可见,理解了生活中的 “信号处理”,就能轻松迁移到 Linux 系统中。

1.1 快递的故事:完美映射信号处理流程

        想象一个场景:你在家打游戏,网购的快递到了,快递员在楼下给你打电话通知取件。这个过程和 Linux 进程处理信号的逻辑几乎一模一样,我们来拆解每一个环节:

  1. 信号识别:你看到快递员的电话,就知道是快递到了,不需要别人额外解释 —— 这对应 Linux 进程对信号的内置识别能力,内核程序员在设计进程时,已经让进程能识别系统中所有合法信号,比如Ctrl+C对应的 2 号信号SIGINT、段错误对应的 11 号信号SIGSEGV
  2. 信号延迟处理:你正在打游戏的关键团战,需要 5 分钟后才能下楼取件 —— 这对应信号的异步特性,进程收到信号后,不会立即处理,而是会在合适的时候处理(比如进程从内核态返回到用户态时),因为进程可能正在执行优先级更高的任务。
  3. 信号暂存:5 分钟内,你虽然没取快递,但心里记着 “有快递要取”—— 这对应信号的暂存机制,进程收到信号后,如果暂时不处理,会将信号保存在进程控制块(PCB)中,直到处理时机到来。
  4. 异步特性:你无法准确知道快递员什么时候会打电话 —— 这对应信号的异步性,信号对于进程的控制流程来说是异步的,进程无法预知信号何时到来,可能在执行代码的任意位置收到信号。

信号的三种处理方式:等你打完游戏取到快递后,会有三种选择:

默认处理:开心地拆开快递,使用里面的商品 —— 对应进程对信号的默认动作,比如SIGINT的默认动作是终止进程,SIGSEGV的默认动作是终止进程并生成核心转储文件。自定义处理:快递是零食,你转手送给了女朋友 —— 对应进程对信号的自定义捕捉,通过注册信号处理函数,让进程收到信号后执行自己定义的逻辑。忽略处理:把快递拿回家扔在床头,继续打游戏 —— 对应进程忽略信号,收到信号后不做任何操作,比如SIGCHLD信号的默认动作就是忽略。

1.2 生活场景到 Linux 信号的核心结论

        从快递的故事,我们可以提炼出 Linux 进程信号的几个核心结论,这是理解信号的关键:

  1. 进程对信号的识别能力是内置的,无需后天学习,内核已经为进程预设了所有合法信号的识别逻辑;
  2. 信号的处理方法在信号产生前就已准备好,进程无论是否收到信号,都知道该如何处理每一种信号(默认 / 忽略 / 自定义);
  3. 信号处理并非立即执行,进程会在合适的时机处理,核心原因是信号具有异步性,且进程可能在执行高优先级任务;
  4. 信号的完整生命周期是:信号产生 → 信号保存 → 信号处理
  5. 信号的处理方式只有三种:默认处理(SIG_DFL)、忽略处理(SIG_IGN)、自定义捕捉(Catch)

二、技术视角:Linux 进程信号的初体验

        理解了生活中的信号逻辑,我们回到 Linux 系统本身,通过实战代码终端操作,直观感受进程信号的存在和作用,搞懂Ctrl+C终止进程的底层原理,以及如何通过代码修改信号的处理方式。

2.1 第一个实验:Ctrl+C的本质 —— 向前台进程发送 2 号信号SIGINT

        我们先写一个简单的死循环 C 程序,让进程一直运行,然后通过Ctrl+C终止它,看看背后发生了什么。

代码实现:sig_hello.c

#include <iostream> #include <unistd.h> using namespace std; int main() { while (true) { cout << "I am a process, my PID is: " << getpid() << ", waiting signal!" << endl; sleep(1); // 每秒打印一次 } return 0; } 

编译运行

# 编译 g++ sig_hello.c -o sig_hello # 运行 ./sig_hello 

        运行后,终端会不断打印进程 PID 和提示信息,此时按下Ctrl+C,进程会立即终止。这背后的底层逻辑是什么?

我们按下Ctrl+C时,键盘输入会产生一个硬件中断,被操作系统(OS)捕获;OS 将这个硬件中断解释为2 号信号 SIGINT(中断信号);OS 将SIGINT信号发送给当前的前台进程(也就是我们运行的sig_hello进程);前台进程收到SIGINT信号后,执行默认处理动作—— 终止进程。

        这就是Ctrl+C终止进程的完整流程,核心是OS 将硬件操作转换为信号,发送给进程并触发默认处理

2.2 第二个实验:修改信号处理方式 —— 让Ctrl+C不再终止进程

        既然进程对信号的处理方式可以自定义,那我们能不能通过代码修改SIGINT信号的处理方式,让按下Ctrl+C后进程不终止,而是执行我们自定义的逻辑?

        答案是肯定的,我们可以使用ANSI C 标准的signal函数来修改信号的处理动作,该函数的作用是为指定信号注册自定义处理函数。

2.2.1 signal函数介绍

#include <signal.h> // 函数指针类型,定义信号处理函数的格式 typedef void (*sighandler_t)(int); // 注册信号处理函数 sighandler_t signal(int signum, sighandler_t handler); 

参数说明

  • signum:要处理的信号编号,比如 2 代表SIGINT,3 代表SIGQUIT

handler:信号处理函数的指针,有三种取值:

自定义函数指针:进程收到信号后执行该函数;SIG_IGN:忽略该信号;SIG_DFL:执行该信号的默认处理动作。返回值:成功返回该信号原来的处理函数指针,失败返回SIG_ERR

2.2.2 代码实现:sig_catch.c

#include <iostream> #include <unistd.h> #include <signal.h> using namespace std; // 自定义信号处理函数 void sig_handler(int signum) { // signum参数会传入当前收到的信号编号 cout << "我是进程[" << getpid() << "],捕获到信号:" << signum << ",我没有终止!" << endl; } int main() { cout << "我是主进程,PID:" << getpid() << endl; // 为2号信号SIGINT注册自定义处理函数 signal(SIGINT, sig_handler); while (true) { cout << "进程正在运行,等待信号..." << endl; sleep(1); } return 0; } 

2.2.3 编译运行

g++ sig_catch.c -o sig_catch ./sig_catch 

        运行后,再次按下Ctrl+C,会发现进程不再终止,而是打印我们自定义的信息,比如:

我是主进程,PID:12345 进程正在运行,等待信号... 进程正在运行,等待信号... ^C我是进程[12345],捕获到信号:2,我没有终止! 进程正在运行,等待信号... 

2.2.4 实验思考:为什么进程不终止了?

        因为我们通过signal函数将SIGINT信号的处理方式从默认终止修改为自定义执行sig_handler函数,进程收到信号后,会执行我们定义的逻辑,而不是默认的终止动作。

        这个实验也印证了一个重要点:signal函数只是设置信号的捕捉行为,并不是直接调用处理函数。如果信号没有产生,注册的自定义函数永远不会被执行。

2.3 关键知识点:前台进程与后台进程的信号差异

        在上面的实验中,我们提到Ctrl+C产生的信号只能发送给前台进程,这是 Linux 系统的一个重要规则,我们需要明确前台进程和后台进程的信号差异:

前台进程:在 Shell 中直接运行的进程,占据终端的输入输出,能接收终端控制键产生的信号,比如Ctrl+C(SIGINT)、Ctrl+\(SIGQUIT)、Ctrl+Z(SIGTSTP);后台进程:在命令后加&运行的进程,不占据终端的输入输出,无法接收终端控制键产生的信号,比如./sig_catch &Shell 的进程管理规则:Shell 可以同时运行一个前台进程任意多个后台进程,只有前台进程能接收终端的信号。

实战验证:后台进程不接收Ctrl+C信号

# 将进程放到后台运行 ./sig_catch & # 查看后台进程 jobs # 此时按下Ctrl+C,后台进程不会收到信号,继续运行 # 想要终止后台进程,可以使用kill命令 kill -2 进程PID # 向进程发送2号信号SIGINT

三、Linux 信号的核心概念:你必须知道的基础定义

        通过前面的实战,我们已经直观感受了信号的作用,接下来我们正式定义 Linux 进程信号的核心概念,为后续深入学习打下理论基础,这些概念是理解信号的基石。

3.1 信号的官方定义

        信号是进程之间事件异步通知的一种方式,属于软中断

异步通知:进程无需主动轮询,信号会在任意时刻到来,进程在合适的时机处理即可;软中断:信号是软件层面模拟硬件中断的机制,硬件中断是发给 CPU 的,而信号是发给进程的,两者的处理流程相似,但作用层级不同。

3.2 如何查看 Linux 系统中的所有信号

        Linux 系统为进程预设了大量信号,编号从 1 开始,其中34 号及以上为实时信号,34 号以下为常规信号(也叫非实时信号),我们日常开发中主要使用常规信号。

        可以通过以下命令查看系统中所有的信号:

# 方式1:kill -l (l是list的缩写) kill -l # 方式2:man 7 signal (查看信号的详细说明,包括产生条件、默认动作) man 7 signal 

        执行kill -l后,终端会输出 Linux 系统的所有信号,部分关键常规信号如下:

信号编号信号名产生条件默认动作
1SIGHUP进程所属的终端挂起终止进程
2SIGINT终端按下 Ctrl+C终止进程
3SIGQUIT终端按下 Ctrl+\终止进程并生成 core dump
9SIGKILLkill -9 进程 PID终止进程(不可捕捉、不可忽略)
11SIGSEGV非法内存访问(段错误)终止进程并生成 core dump
14SIGALRM闹钟超时(alarm 函数)终止进程
15SIGTERMkill 进程 PID(默认信号)终止进程(可捕捉、可忽略)
17SIGCHLD子进程终止 / 暂停忽略信号
20SIGTSTP终端按下 Ctrl+Z暂停进程

        重要注意:9 号信号SIGKILL和 19 号信号SIGSTOP是 Linux 系统中不可捕捉、不可忽略的信号,这是为了保证操作系统能绝对控制进程,避免进程通过自定义信号处理方式变成 “无法杀死的僵尸进程”。

3.3 信号的三种处理动作

        正如我们在生活场景中总结的,Linux 进程对信号的处理动作只有三种,这是内核为进程预设的基本规则,所有信号都遵循这个规则:

3.3.1 执行默认动作(SIG_DFL)

        这是绝大多数信号的默认处理方式,不同信号的默认动作不同,主要包括:

Term:终止进程(如 SIGINT、SIGTERM、SIGALRM);Core:终止进程并生成 core dump 文件(如 SIGQUIT、SIGSEGV、SIGFPE),core dump 文件用于事后调试;Stop:暂停进程(如 SIGTSTP、SIGSTOP);Cont:继续运行暂停的进程(如 SIGCONT);Ign:忽略信号(如 SIGCHLD)。

3.3.2 忽略信号(SIG_IGN)

        进程收到信号后,不做任何操作,直接忽略。比如我们可以通过signal(SIGINT, SIG_IGN)让进程忽略Ctrl+C信号,此时按下Ctrl+C,进程不会有任何反应。

代码验证:忽略 SIGINT 信号

#include <iostream> #include <unistd.h> #include <signal.h> using namespace std; int main() { cout << "进程PID:" << getpid() << ",已忽略SIGINT信号" << endl; // 忽略2号信号SIGINT signal(SIGINT, SIG_IGN); while (true) { cout << "进程正在运行..." << endl; sleep(1); } return 0; } 

        编译运行后,无论按多少次Ctrl+C,进程都不会终止,因为进程已经忽略了SIGINT信号。

3.3.3 自定义捕捉(Catch)

        通过signalsigaction函数为信号注册自定义处理函数,进程收到信号后,执行我们定义的逻辑,这是信号最灵活的处理方式,也是开发中最常用的方式。

        前面的sig_catch.c就是自定义捕捉的典型例子,这里再补充一个关键点:自定义处理函数的参数。自定义信号处理函数的格式是void handler(int signum),其中signum参数会自动传入当前收到的信号编号,这让我们可以用一个函数处理多个信号

代码验证:一个函数处理多个信号

#include <iostream> #include <unistd.h> #include <signal.h> using namespace std; // 一个函数处理多个信号 void sig_handler(int signum) { switch (signum) { case 2: cout << "捕获到SIGINT(2号)信号,Ctrl+C无效!" << endl; break; case 3: cout << "捕获到SIGQUIT(3号)信号,Ctrl+\\无效!" << endl; break; case 20: cout << "捕获到SIGTSTP(20号)信号,Ctrl+Z无效!" << endl; break; default: cout << "捕获到未知信号:" << signum << endl; break; } } int main() { cout << "进程PID:" << getpid() << ",已注册多信号处理函数" << endl; // 为2、3、20号信号注册同一个处理函数 signal(SIGINT, sig_handler); signal(SIGQUIT, sig_handler); signal(SIGTSTP, sig_handler); while (true) { cout << "进程正在运行..." << endl; sleep(1); } return 0; } 

        编译运行后,按下Ctrl+CCtrl+\Ctrl+Z,进程都会执行对应的自定义逻辑,而不是默认动作,实现了一个函数处理多个信号的效果。

3.4 信号的宏定义

        在 Linux 系统中,所有信号的名称都是宏定义,对应的头文件是<signal.h>,宏定义的本质是将信号编号转换为易记的名称,方便开发人员使用。

        比如<signal.h>中的部分宏定义:

#define SIGINT 2 // 中断信号 #define SIGQUIT 3 // 退出信号 #define SIGKILL 9 // 杀死信号 #define SIGSEGV 11 // 段错误信号 #define SIGTERM 15 // 终止信号 #define SIGCHLD 17 // 子进程状态变化信号 #define SIGTSTP 20 // 暂停信号 // 信号处理动作的宏定义 #define SIG_DFL ((__sighandler_t) 0) // 默认动作 #define SIG_IGN ((__sighandler_t) 1) // 忽略信号 

        可以看到,SIG_DFLSIG_IGN本质上是将 0 和 1 强制转换为信号处理函数的指针类型,让它们能作为signal函数的第二个参数。

四、信号的异步性:进程控制流程的 “意外插曲”

        信号的异步性是其最核心的特性之一,也是理解信号的关键难点,我们需要单独拿出来重点讲解,因为它决定了信号的处理时机和方式。

4.1 什么是信号的异步性

        所谓异步,是相对于同步而言的:

同步执行:进程的代码按顺序执行,执行完一行再执行下一行,流程完全可控;异步事件:信号会在任意时刻到来,进程无法预知信号的产生时间,可能在执行代码的任意位置收到信号,比如进程在执行循环、函数调用、系统调用时,都可能收到信号。

        举个例子:进程正在执行for循环的第 100 次迭代,此时 OS 向进程发送了SIGINT信号,进程会在合适的时机暂停循环,处理信号,处理完成后再继续执行循环的第 100 次迭代,这就是异步性的体现。

4.2 为什么信号不能立即处理

        很多初学者会有疑问:进程收到信号后,为什么不立即处理,而是要等到 “合适的时机”?主要有两个原因:

进程可能在执行高优先级任务:比如进程正在执行内核态的代码(如系统调用),此时处理信号可能会破坏内核数据结构,导致系统崩溃,因此需要等进程从内核态返回到用户态时再处理;信号处理的原子性:如果进程在执行一个不可中断的操作(如修改全局变量),此时处理信号可能会导致数据不一致,因此需要等操作完成后再处理。

4.3 信号的处理时机:内核态 → 用户态的切换时刻

        Linux 进程的运行状态分为用户态内核态

用户态:进程执行自己的用户代码(如我们写的 C/C++ 代码),权限较低,不能直接访问硬件和内核数据;内核态:进程执行内核代码(如系统调用、中断处理),权限较高,可以访问硬件和内核数据。

        进程的一生会在用户态内核态之间不断切换,比如:

进程调用readwritesleep等系统调用时,会从用户态切换到内核态;系统调用执行完成后,进程会从内核态切换回用户态。

        信号的处理时机进程从内核态返回到用户态的瞬间,OS 会检查进程的 PCB 中是否有未处理的信号,如果有,就会先处理信号,处理完成后再返回到用户态执行进程的正常代码。

        这是 Linux 系统规定的唯一信号处理时机,也是保证信号处理安全性的关键。

五、常见终端信号的实战:除了 Ctrl+C,还有这些操作

        除了Ctrl+C对应的SIGINT信号,我们在终端中常用的Ctrl+\Ctrl+Z也会产生对应的信号,分别是SIGQUIT(3 号)和SIGTSTP(20 号),我们来实战验证这两个信号的作用,进一步加深对信号的理解。

5.1 Ctrl+\:SIGQUIT 信号,终止进程并生成 core dump

    SIGQUIT信号的默认动作是终止进程并生成 core dump 文件,core dump 文件是进程的内存镜像文件,包含了进程终止时的内存数据、寄存器状态等信息,用于事后调试(Post-mortem Debug)。

实战验证:SIGQUIT 信号的默认动作

# 运行之前的死循环程序 ./sig_hello # 按下Ctrl+\,进程终止并生成core dump文件 ^\Quit (core dumped) # 查看当前目录下的core文件 ls -l core* 

        注意:Linux 系统默认关闭 core dump 功能,若没有生成 core 文件,可以通过以下命令开启:

# 设置core文件的最大大小为1024KB(临时生效,重启Shell后失效) ulimit -c 1024 # 查看core文件限制 ulimit -a 

5.2 Ctrl+Z:SIGTSTP 信号,暂停前台进程

    SIGTSTP信号的默认动作是暂停前台进程,将进程从前台切换到后台,状态变为Stopped,暂停的进程可以通过fg命令恢复到前台,或通过bg命令让其在后台继续运行。

实战验证:SIGTSTP 信号的默认动作

# 运行死循环程序 ./sig_hello # 按下Ctrl+Z,进程被暂停 ^Z[1]+ Stopped ./sig_hello # 查看后台暂停的进程 jobs # 将暂停的进程恢复到前台运行 fg %1 # 将暂停的进程在后台继续运行 bg %1 # 终止后台进程 kill -9 进程PID 

        我们也可以通过signal函数自定义SIGQUITSIGTSTP信号的处理方式,让它们不再执行默认动作,代码和前面的sig_catch.c类似,只需将信号编号改为 3 和 20 即可。


总结

        Linux 进程信号是操作系统的核心知识点,也是面试的高频考点,想要真正掌握信号,不能只看理论,一定要多写代码、多做实验,从实战中理解信号的逻辑。本文的所有代码都可以直接编译运行,建议大家亲手敲一遍,感受信号的魅力。后续我会继续更新信号的进阶内容,敬请关注!        

Read more

Flutter for OpenHarmony:Flutter 三方库 objectid — 离线分布式高可用 ID 引擎

Flutter for OpenHarmony:Flutter 三方库 objectid — 离线分布式高可用 ID 引擎

欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区 前言 如果在利用鸿蒙(OpenHarmony)构建具备“去中心化”、“集群防碰撞协同”或者是大宗“断网盘点及复杂离线同步”的系统时,我们仍然幼稚地使用类似 1, 2, 3 这样的自增数字作为数据库主键,那么在设备恢复网络并尝试向云端同步的那一刻,必然会爆发大规模的主键覆盖与冲突,从而引发系统的毁灭性崩塌。 如果您不想引入极为冗长、解析缓慢且极占存储宽带的 UUID,那么彻底源于 MongoDB 内核设计的原生且硬核的发号器:objectid,绝对是你在大型离线应用开发中的最佳选择!它不仅能将复杂的主键标识压缩在极小的 12 字节空间内,更利用极致的编码策略,原生隐蔽携带有“精确生成时间戳”、“端设备唯一标识印戳”以及“抗压极高的高频自增段”等多维复合关键大信息! 一、原理解析 / 概念介绍 1.1 基础概念 这套发号引擎通过严密的序列特征输出,将 4 字节的毫秒级时间戳、5 字节的机器特征码和 3

By Ne0inhk
Flutter 组件 reaxdb_dart 适配鸿蒙 HarmonyOS 实战:响应式 NoSQL 数据库,构建高性能本地持久化与分布式状态同步架构

Flutter 组件 reaxdb_dart 适配鸿蒙 HarmonyOS 实战:响应式 NoSQL 数据库,构建高性能本地持久化与分布式状态同步架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 reaxdb_dart 适配鸿蒙 HarmonyOS 实战:响应式 NoSQL 数据库,构建高性能本地持久化与分布式状态同步架构 前言 在鸿蒙(OpenHarmony)生态迈向全场景协同、涉及极高频率的端侧数据持久化、实时 UI 数据绑定及分布式节点状态同步的背景下,如何实现一套既能保障数据“强一致性”、又能提供毫秒级检索性能且具备天然“响应式(Reactive)”特性的本地存储引擎,已成为决定应用交互流畅度与底层架构灵活性。在鸿蒙设备这类强调 AOT 极致效能与沙箱存储严格隔离的环境下,如果应用依然依赖臃肿的传统 SQL 或非响应式的 Key-Value,由于由于由于由于 UI 与数据库间的频繁轮询,极易由于由于“数据 IO 阻塞”导致鸿蒙应用在高并发读写时发生明显的帧率抖动。 我们需要一种能够解耦存储逻辑、支持 Stream 级变更监听且具备高性能二进制序列化架构的嵌入式

By Ne0inhk
Python入门:Python3 PyMySQL 驱动操作数据库全面学习教程

Python入门:Python3 PyMySQL 驱动操作数据库全面学习教程

Python入门:Python3 PyMySQL 驱动操作数据库全面学习教程 Python入门:Python3 PyMySQL 驱动操作数据库全面学习教程,本文是关于 Python3 使用 PyMySQL 驱动操作 MySQL 数据库的教程,首先介绍了 PyMySQL 的定义,它是 Python3 连接 MySQL 的库,遵循特定规范。接着讲解了多种安装方法及常见问题解决,然后说明连接数据库的准备工作,还详细演示了连接数据库、创建表、增删改查等核心操作,同时介绍了事务处理的方法和特性,以及各类错误异常的相关内容,帮助初学者快速掌握相关技能。 前言     Python作为一门简洁、易读、功能强大的编程语言,其基础语法是入门学习的核心。掌握好基础语法,能为后续的编程实践打下坚实的基础。本文将全面讲解Python3的基础语法知识,适合编程初学者系统学习。Python以其简洁优雅的语法和强大的通用性,成为当今最受欢迎的编程语言。本专栏旨在系统性地带你从零基础入门到精通Python核心。无论你是零基础小白还是希望进阶的专业开发者,都将通过清晰的讲解、丰富的实例和实战项目,逐步掌握语法基

By Ne0inhk
从海量时序数据到无人值守:数据库在新能源集控系统中的架构实践

从海量时序数据到无人值守:数据库在新能源集控系统中的架构实践

文章目录 * 引言 * 关于金仓数据库 * 金仓数据库在新能源行业的技术解读 * 1. 应对海量时序数据:分区存储与高效查询 * 2. 支撑高并发访问:读写分离与自治调优 * 3. 保障业务连续性:跨地域高可用与容灾 * 4. 实现平滑迁移:高度兼容与自动化工具 * 案例分析:金仓数据库赋能新能源智慧运维 * 案例一:中广核新能源生产运维系统——应对“整合、高并发、高可用”三大挑战 * 案例二:国家能源集团龙源电力——186个新能源场站集控系统国产化替代 * 案例三:国家电投集团甘肃新能源——“无人值守”风电场集控系统 * 结语 引言 谈到“双碳”与能源革命,风电,光伏这些新能源产业显然是当下最为炙手可热的风口,若想在该赛道跑得更远,更快,数字化和智能化转型并非可选,而是必备功课,要知道,从远程操控成千上万台风电机组,到及时分析大量的设备数据,直至把整个生产运维流程管理得井井有条,哪一步能离开稳定,高效且安全的数据“大后方”

By Ne0inhk