当前位置: 首页 > news >正文

Linux操作系统之进程信号

进程信号

  • 一、信号
    • 1、概念
    • 2、系统定义的信号列表
    • 3、常见的信号处理方式
  • 二、产生信号的方式
    • 1、终端按键
      • (1)组合键
      • (2)示例代码
      • (3)运行结果
    • 2、调用系统函数
      • (1)kill命令
      • (2)kill函数
        • 【1】函数
        • 【2】描述
      • (3)raise函数
        • 【1】函数
        • 【2】描述
      • (4)abort函数
        • 【1】函数
        • 【2】描述
    • 3、软件条件
      • (1)alarm函数
      • (2)描述
      • (3)示例代码
      • (4)运行结果
    • 4、硬件异常
  • 三、阻塞信号
    • 1、概念
    • 2、信号在内核中的示意图
    • 3、解释
  • 四、信号集
    • 1、sigset_t
      • (1)定义
      • (2)应用
    • 2、信号集操作函数
      • (1)函数
      • (2)描述
      • (3)返回值
    • 3、sigprocmask函数
      • (1)函数
      • (2)描述
      • (3)参数how的有效值
    • 4、sigpending函数
      • (1)函数
      • (2)描述
    • 5、示例代码
  • 五、信号捕捉
    • 1、捕捉信号
      • (1)概念
      • (2)过程示意图
    • 2、signal函数
      • (1)函数
      • (2)描述
    • 3、sigaction函数
      • (1)函数
      • (2)描述
    • 4、可重入函数
      • (1)概念
  • 六、SIGCHLD信号

一、信号

1、概念

  • 在Linux中用于进程间通信和控制的一种机制,是进程之间事件异步通知的一种方式,属于软中断。
  • 所有信号的产生,最终都要由OS来进行执行,因为OS是进程的管理者。
  • 信号的处理可以不立即处理,而在合适的时候再处理。它有一个时间窗口,在这个时间窗口内,必须记住信号的到来。
  • 尽管进程没有收到信号,它也要知道对合法信号的处理操作,这属于进程内置功能的一部分。

2、系统定义的信号列表

在这里插入图片描述

  • 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到。
  • 编号34以下的信号为普通信号,编号34及以上的信号为实时信号。
  • 信号 SIGKILL 和 SIGSTOP 无法被捕获或者忽略。

3、常见的信号处理方式

  • SIG_IGN:忽略信号。
  • SIG_DFL:执行信号的默认处理动作。
  • 捕捉信号:提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数。

二、产生信号的方式

1、终端按键

(1)组合键

  • Ctrl + c:信号2(SIGINT)。
  • Ctrl + \:信号3(SIGQUIT)。

(2)示例代码

void handler(int signo)
{cout << "get a signo: " << signo << endl;
}int main()
{for(int i = 1; i <= 31; ++i){signal(i, handler);}while(true){cout << "I am a crazy process" << " pid = " << getpid() << endl;sleep(1);}return 0;
}

(3)运行结果

在这里插入图片描述

在这里插入图片描述

2、调用系统函数

(1)kill命令

  • 命令行输入:kill -signo pid

(2)kill函数

【1】函数

在这里插入图片描述

【2】描述
  • kill函数,即系统调用,可用于向任何进程或进程组发送任何信号。
  • 如果 pid 为正数,则将 sig 信号发送到 pid 指定的进程。
  • 如果 pid 等于 0,则 sig 信号将发送到调用进程的进程组中的每个进程。
  • 如果 pid 等于 -1,则 sig 信号将发送到调用进程有权发送信号的每个进程,但进程1(init)除外。
  • 如果 pid 小于 -1,则 sig 将发送到进程组中 ID 为 -pid 的每个进程。
  • 如果 sig 为 0,则不发送信号,但仍执行错误检查。这可用于检查进程 ID 或进程组 ID 是否存在。

(3)raise函数

【1】函数

在这里插入图片描述

【2】描述
  • raise函数向调用进程或线程发送 sig 信号。
  • 在单线程程序中,它等价于 kill(getpid(), sig);
  • 在多线程程序中,它等价于 pthread_kill(pthread_self(), sig);
  • 如果信号有自定义的处理函数,则raise函数只有在该函数返回后才会返回。

(4)abort函数

【1】函数

在这里插入图片描述

【2】描述
  • abort函数首先取消 SIGABRT 信号的阻塞状态,然后为调用它的进程引发该信号。 而这会导致进程异常终止,除非 SIGABRT 信号被捕获并且信号处理程序(自定义的信号处理方法)没有返回。
  • 如果abort函数导致进程终止,则关闭并刷新所有打开的流。
  • 如果 SIGABRT 信号被忽略,或被返回的处理程序(自定义的信号处理方法)捕获,则 abort函数仍将终止进程。 它通过恢复 SIGABRT 的默认配置,然后再次引发该信号来实现此目的。

3、软件条件

(1)alarm函数

在这里插入图片描述

(2)描述

  • alarm函数安排在seconds秒后将 SIGALRM 信号传送到调用进程。
  • 如果秒数为零,则取消任何挂起的警报。
  • 在任何情况下,任何先前用alarm函数设置的“闹钟”都会被取消。
  • alarm函数的返回值为,如果没有先前安排的“闹钟”,则返回零;反之,返回距离任何先前安排的“闹钟”发出 SIGALRM 信号的剩余秒数。

(3)示例代码

void handler(int signo)
{cout << "get signo: " << signo << endl;unsigned int n = alarm(5);cout << "剩余时间:" << n << endl;
}int main()
{signal(SIGALRM, handler);alarm(50);while(true){cout << "this process pid: " << getpid() << endl;sleep(1);}return 0;
}

(4)运行结果

在这里插入图片描述
在这里插入图片描述

4、硬件异常

硬件异常被硬件以某种方式检测到并通知内核,然后内核向当前进程发送适当的信号。

三、阻塞信号

1、概念

  • 信号递达(Delivery):执行信号的处理动作。
  • 信号未决(Pending):信号从产生到递达之间的状态。
  • 信号阻塞(Block):被阻塞的信号产生时将保持在未决状态,直到进程解除对该信号的阻塞才能执行递达的动作,即只要信号被阻塞就不会递达。

2、信号在内核中的示意图

在这里插入图片描述

3、解释

  • 标志位block是信号阻塞,标志位pending是信号未决,1表示设置,0表示未设置。函数指针表handler是信号的处理方法。
  • 信号产生时,内核在进程控制块中设置该信号的未决标志(置1),直到信号递达才清除该标志(置0)。
  • 在上方的图中,SIGHUP信号产生过,但是被阻塞了,所以暂时不能递达,当它递达时执行默认处理动作;SIGINT信号未产生过且被阻塞了,当产生SIGINT信号时,该信号将会被阻塞,即pending只将该信号的位置置为1而不会递达。它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号。因为进程仍有机会改变处理动作之后再解除阻塞。SIGQUIT信号未阻塞也未产生过,它的处理动作是用户自定义函数sighandler。
  • 在Linux中,常规信号在进程解除阻塞之前如果产生过多次,则在递达之前只计一次。而实时信号如果在递达之前产生过多次可以依次放在一个队列里,即实时信号的每一次产生都有效。

四、信号集

1、sigset_t

(1)定义

在这里插入图片描述
在这里插入图片描述

(2)应用

  • 在标志位block和pending中,每个信号只有一个bit的标志,即非0即1,不会记录对应信号产生的次数。
  • sigset_t:信号集,阻塞(block)和未决(pending)标志可以用它来存储,这个类型可以表示每个信号的“有效”或“无效”状态。
  • 在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。
  • 阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask)。

2、信号集操作函数

(1)函数

在这里插入图片描述

(2)描述

  • sigemptyset:将 set 给出的信号集初始化为空,即将所有的信号都从集合中排除。
  • sigfillset:将 set 初始化为 full,即将所有信号都设置在内。
  • sigaddset:添加 set 中signum对应的信号。
  • sigdelset:删除 set 中signum对应的信号。
  • sigismember:测试 signum 是否是 set 的成员,即测试 signum 是否在set 中。
  • sigset_t 类型的对象必须通过调用 sigemptyset 或 sigfillset 进行初始化,然后才能传递给函数 sigaddset、sigdelset和 sigismember;或者下面描述的其他 glibc 函数(sigisemptyset()、sigandset() 和 sigorset())。 如果不这样做,结果是未定义的。

(3)返回值

  • sigemptyset、sigfillset、sigaddset 和 sigdelset 成功时返回 0,错误时返回 -1。
  • 对于sigismember来说,如果 signum 是 set 的成员,则返回 1,如果 signum 不是 set 的成员,则返回 0,错误时返回 -1。
  • 出错时,这些函数会设置 errno 以指示原因。

3、sigprocmask函数

(1)函数

在这里插入图片描述

(2)描述

  • sigprocmask函数用于获取和/或更改调用线程的信号掩码。
  • sigprocmask函数调用的行为取决于 how 的值。
  • 如果 oldset 为非 NULL,则信号掩码的上一个值将存储在 oldset 中。
  • 如果 set 为 NULL,则信号掩码保持不变(即忽略 how),但信号掩码的当前值仍通过 oldset 返回(如果它不是 NULL)。

(3)参数how的有效值

  • SIG_BLOCK:阻塞信号集将被设置为当前信号集和参数 set 的并集,即将 set 中包含的信号都阻塞。
  • SIG_UNBLOCK:参数 set 集合中的信号将从当前受阻信号集中移除,即 set 中包含的信号将被设置为不阻塞。 允许尝试解锁未被阻塞的信号。
  • SIG_SETMASK:将阻塞信号集的内容设置为参数 set 的内容。

4、sigpending函数

(1)函数

在这里插入图片描述

(2)描述

  • sigpending函数返回等待传送到调用线程的信号集(即在被阻塞时引发的信号)。
  • 挂起信号的掩码在参数set中返回。

5、示例代码

#include<iostream>
#include<unistd.h>
#include<signal.h>
using namespace std;void PrintSignal(const sigset_t& pending)
{for(int i = 31; i >= 1; --i){if(sigismember(&pending, i))cout << "1";elsecout << "0";}cout << "\n" << endl;
}int main()
{sigset_t bset, oset;sigemptyset(&bset);sigemptyset(&oset);for(int i = 1; i <= 31; ++i){sigaddset(&bset, i);}sigprocmask(SIG_SETMASK, &bset, &oset);sigset_t pending;sigemptyset(&pending);while(true){int ret = sigpending(&pending);if(ret == -1)continue;PrintSignal(pending);sleep(1);}return 0;
}

五、信号捕捉

1、捕捉信号

(1)概念

  • 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数。
  • 当我们的进程从内核态返回到用户态的时候,进行信号的检测和处理。

(2)过程示意图

在这里插入图片描述

2、signal函数

(1)函数

在这里插入图片描述

(2)描述

  • signal函数的行为在 UNIX 版本中各不相同,在不同版本的 Linux 中也存在差异。
  • signal函数将 signum 信号的处置(处理方法)设置为处理程序handler,该处理程序是SIG_IGN、SIG_DFL或自定义函数(handler)的地址。
  • 如果 signum 信号被传送到进程,则会发生以下情况之一。如果处置(处理方法)设置为 SIG_IGN,则忽略该信号;如果处置设置为 SIG_DFL,则发生与该信号关联的默认操作;如果处置设置为自定义函数(handler),则首先将处置重置为 SIG_DFL,或者信号被阻止,然后使用参数 signum 调用处理程序(handler)。 如果调用处理程序导致信号被阻塞,则信号在从句柄(handler)返回时被解除阻塞。
  • signal函数返回值为,当调用成功时,返回信号处理程序的上一个值,失败则返回SIG_ERR,并设置errno,用来指示错误原因。

3、sigaction函数

(1)函数

在这里插入图片描述
在这里插入图片描述

(2)描述

  • sigaction系统调用用于更改进程在接收到特定信号时所采取的操作。
  • signum:指定信号,可以是除 SIGKILL 和 SIGSTOP 之外的任何有效信号。
  • 如果 act 为非 NULL,则signum信号的处理操作设置为 act 中sa_handler设定的操作。 如果 oldact 为非NULL,则signum信号的上一个处理操作保存在 oldact 中。
  • 在某些涉及联合体的体系结构中,不要同时分配(设置)给sa_handler和sa_sigaction。
  • sa_restorer:元素已过时,不应使用。 POSIX 未指定 sa_restorer 元素。
  • sa_handler:指定要与 signum 关联的操作,可以设置为SIG_DFL默认操作、SIG_IGN忽略操作或指向信号处理函数的指针,此函数接收信号编号作为其唯一参数。通过用自定义函数就可以用同一个函数处理多种信号,即它是一个回调函数,不过不是被main函数调用,而是被系统所调用。
  • sa_mask:指定在执行信号处理程序期间应阻止的信号掩码(即添加执行信号到调用信号处理程序的线程的信号掩码中),除了当前信号被自动屏蔽之外,也可以通过设置它来自动屏蔽另外一些信号。 此外,触发处理程序的信号将被阻止,除非使用 SA_NODEFER 标志。
  • 当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字。这样就保证了在处理某个信号时,如果这种信号再次产生,那么它会被阻塞到当前处理函数执行结束为止。

4、可重入函数

(1)概念

  • 如果一个函数,被重复进入的情况下,出错或者可能出错,则为不可重入函数。反之,为可重入函数。

六、SIGCHLD信号

  • 子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数。
  • 父进程自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程。当子进程终止时会通知父进程,然后父进程在信号处理函数中调用wait相关函数清理子进程,这是解决僵尸问题的一种方法,前提是父进程不提前退出。
  • 父进程调用sigaction将SIGCHLD的处理动作设置为SIG_IGN。这样用fork函数创建出来的子进程在终止时会被自动清理掉,而不会产生僵尸进程和通知父进程。系统默认的忽略动作和用户用sigaction函数自定义的忽略通常是没有区别的。但这是一个特例,此方法对于Linux可用,但不保证在其它类UNIX系统上都可用。

本文到这里就结束了,如有错误或者不清楚的地方欢迎评论或者私信
创作不易,如果觉得博主写得不错,请点赞、收藏加关注支持一下💕💕💕

相关文章:

Linux操作系统之进程信号

进程信号 一、信号1、概念2、系统定义的信号列表3、常见的信号处理方式 二、产生信号的方式1、终端按键&#xff08;1&#xff09;组合键&#xff08;2&#xff09;示例代码&#xff08;3&#xff09;运行结果 2、调用系统函数&#xff08;1&#xff09;kill命令&#xff08;2&…...

科普文:微服务之Spring Cloud Alibaba消息队列组件RocketMQ工作原理

概叙 本文探讨 RocketMQ 的事务消息原理&#xff0c;并从源码角度进行分析&#xff0c;以及事务消息适合什么场景&#xff0c;使用事务消息需要注意哪些事项。 同时详细介绍RocketMQ 事务消息的基本流程&#xff0c;并通过源码分析揭示了其内部实现原理&#xff0c;尽管事务消…...

黑马头条vue2.0项目实战(五)——首页—频道编辑

目录 1. 使用页面弹出层 1.1 页面弹出层简单使用 1.2 创建频道编辑组件 1.3 页面布局 2. 展示我的频道 3. 展示推荐频道列表 3.1 获取所有频道 3.2 处理展示推荐频道 4. 添加频道 5. 编辑频道 5.1 处理编辑状态 5.2 切换频道 5.3 让激活频道高亮 5.4 删除频道 6.…...

Java:基础语法

基础语法 1. 基本结构类和方法 2. 变量和数据类型基本数据类型引用数据类型 3. 操作符算术操作符比较操作符逻辑操作符 4. 控制结构条件语句循环语句 5. 数组6. 方法7. 面向对象编程类和对象继承多态 8. 异常处理9. 常用类库 1. 基本结构 类和方法 Java程序的基本单位是类&am…...

安装bedtools详细步骤和详细介绍bedtools用法

安装bedtools详细步骤和详细介绍bedtools用法 一、安装bedtools详细步骤下载解压安装编译依赖编译设置环境变量激活环境变量执行命令查看版本二、详细介绍bedtools用法使用bedtools示例用法bedtools intersectbedtools bamtobedbedtools window一、安装bedtools详细步骤 下载 …...

21 - grace数据处理 - 补充 - 泄露误差改正 - Slepian局部谱分析法(一) - slepian分析法理论理解

21 - grace数据处理 - 泄露误差改正 - Slepian局部谱分析法 - slepian分析法理论理解 0 引言1 slepian谱分析法1.1 slepian谱分析法AI解释1.2 基于slepian谱分析法的GRACE数据处理应用2 slepian谱分析法关键过程实现2.1 求解正定特征方程2.2 计算slepian基函数2.3 计算Shannon数…...

WLAN国家码与信道顺从表

国家码和信道顺从表及信道功率限制 不同的国家和地区规定了在本国或本地区可以使用的信道、射频信号在信道中的最大发射功率。工作在不同信道的射频信号&#xff0c;信号强度可能会有差别。国家码和信道顺从表、各信道的功率限制值、信道编号和频率对照关系请参见国家码和信道…...

行为型设计模式1:状态/策略/命令

行为型设计模式&#xff1a;状态/策略/命令 (qq.com)...

【知识专栏丨python数分实战】天猫订单数据分析及可视化|taobao天猫订单接口

今天这篇文章将给大家介绍天猫订单数据分析及可视化案例。 import pandas as pdimport numpy as npfrom pyecharts.charts import Pie,Bar,Line,Map,Map3D,Funnelfrom pyecharts import options as optsimport matplotlib.pyplot as pltimport warningsimport seaborn as snsfr…...

[kimi笔记]为什么csc.exe不可以双击运行

csc.exe 是 C# 编译器的可执行文件&#xff0c;它是 .NET Framework 的一部分&#xff0c;用于编译 C# 源代码文件&#xff08; .cs 文件&#xff09;生成可执行文件&#xff08; .exe 文件&#xff09;或其他类型的程序集。 csc.exe 不能通过双击运行的原因有以下几点&…...

护眼大路灯哪个牌子好?2024学生护眼大路灯推荐

护眼大路灯哪个牌子好&#xff1f;护眼大路灯不仅能够提供日常的光线照明&#xff0c;还模拟了太阳光光线&#xff0c;使在室内用眼学习也能够有着自然光般的舒适感&#xff0c;但现在市场上有许多对产品质量把控不过关、光线效果欠佳、存有安全隐患的劣质护眼大路灯产品&#…...

Vue项目中手搓滑动校验模块-demo

实现代码 SliderCheck.vue <template><div class"drag" ref"dragDiv"><div class"drag_bg" ref"dragBg"></div><div class"drag_text" ref"dragText">{{ confirmWords }}</di…...

Socket如何实现客户端和服务器间的通信

Socket 是实现网络通信的一种机制&#xff0c;它允许在不同主机之间的进程通过网络进行数据交换。下面我将简要介绍如何使用 Socket 实现客户端和服务器间的通信。 客户端-服务器通信步骤&#xff1a; 服务器端&#xff1a; 创建服务器端 Socket&#xff1a; 服务器端通过创…...

基于Spring boot + Vue的校园论坛

作者的B站地址&#xff1a;程序员云翼的个人空间-程序员云翼个人主页-哔哩哔哩视频 csdn地址&#xff1a;程序员云翼-CSDN博客 1.项目技术栈&#xff1a; 前后端分离的项目 后端&#xff1a;Springboot MybatisPlus 前端&#xff1a;Vue ElementUI 数据库&#xff1a; …...

RabbitMQ高级特性 - 生产者消息确认机制

文章目录 生产者消息确认机制概述confirm 代码实现return 代码实现 生产者消息确认机制 概述 为了保证信息 从生产者 发送到 队列&#xff0c;因此引入了生产者的消息确认机制. RabbitMQ 提供了两种解决方案&#xff1a; 通过事务机制实现.通过发送确认机制&#xff08;confi…...

webpack的loader机制

webpack的loader机制 loader本质上就是导出函数的JavaScript模块。导出的函数&#xff0c;可以用来实现内容的转换。 /* * param{string|Buffer} content 源文件的内容 * param{object} [map] SourceMap数据 * param{any} [meta] meta数据&#xff0c;可以是任何数据 * */ fu…...

(STM32笔记)十一、通过EXTI外部中断实现 按键控制LED

我用的是正点的STM32F103来进行学习&#xff0c;板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话&#xff0c;用的也是这个板子和教程。 十一、通过EXTI外部中断实现 按键控制LED 十一、通过EXTI外部中断实现 按键控制LED1、按键模块按键原理图按键程序思路 2、中…...

假如家里太大了,wifi连不上了怎么办

最近有个土豪朋友抱怨&#xff0c;他家里太大了&#xff0c;一个路由器的Wi-Fi信号根本无法覆盖他们家的每个房间&#xff0c;都没办法上网看奥运会比赛了。&#xff08;还好我是穷人&#xff0c;就没有这种烦恼T_T&#xff09;。 然后我问他为何不用一个路由器作主路由器&…...

elementPlus 设置el-input文本域固定高度和禁止下拉

elementPlus 设置el-input文本域固定高度和禁止下拉 话不多说直接上代码 // resize"none" 禁止下拉<el-inputv-model"textarea"style"width: 240px"type"textarea"resize"none"placeholder"请输入"/>// 设…...

(转)领导人必过的三道关

为什么企业领导人享受优厚的待遇&#xff0c;为什么董事会对企业领导人千挑万选?因为企业生命如此脆弱&#xff0c;据美国《财 富》杂志报道&#xff0c;世界500强企业平均寿命40年&#xff0c;世界1000强企业平均寿命30年&#xff0c;一般跨国公司平均寿命10年。而就是这脆弱…...

速盾:cdn可以定时刷新缓存吗?

CDN&#xff08;Content Delivery Network&#xff09;是一种通过在全球各地分布的服务器上缓存和传送网站内容的技术&#xff0c;以提高用户访问速度和降低服务器负载。CDN的缓存机制可以减少用户对源服务器的请求次数&#xff0c;从而提高网站的响应速度和性能。但是&#xf…...

代码随想录算法训练营第二十九天| 62.不同路径、63. 不同路径 II

写代码的第二十九天 继续动归&#xff01;&#xff01;&#xff01; 62.不同路径 思路 解决问题1&#xff1a;dp[i][j]的的含义是什么&#xff1f;本题给的是一个二维的表&#xff0c;判断从左上角走到右下角有多少种路径&#xff0c;所以dp应该是二维数组&#xff0c;dp[i]…...

Go+Redis零基础到用户管理系统API实战_20240730 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227 基础不好的同学每节课的代码最好配合视频进…...

ScreenAgent:基于LVLM的计算机控制智能体

ScreenAgent : A Vision Language Model-driven Computer Control Agent 论文链接: https://arxiv.org/abs/2402.07945https://arxiv.org/abs/2402.07945IJCAI 2024 1.概述 大型语言模型(LLM),诸如ChatGPT与GPT-4,在自然语言处理领域(涵盖生成、理解及对话等任务)展现出…...

谷粒商城实战笔记-129-商城业务-商品上架-nested数据类型场景

文章目录 扁平化处理扁平化处理导致的检索问题 解决方案&#xff1a;使用 nested 结构 在es的数据类型中有一个nested类型&#xff0c;本讲将重点讨论这个类型。 扁平化处理 PUT my_index/doc/1 {"group" : "fans","user" : [{"first&quo…...

axios请求响应拦截器

目录 axios-拦截器 拦截器的作用 请求拦截器-基本写法: axios请求拦截器-统一设置token 需求: 核心步骤: 关键代码: 响应拦截器-基本写法: axios响应拦截器-统一处理token失效 需求: 核心步骤: 关键代码: axios响应拦截器-数据剥离 需求: 核心步骤: 关键代码: ax…...

Python 中单例模式实现的几种方式

在设计模式中&#xff0c;单例模式是经常被提及和使用的一种模式。它保证一个类只有一个实例&#xff0c;并提供全局访问点。在Python中&#xff0c;有多种实现单例模式的方法。那么&#xff0c;如何选择合适的方法来实现单例模式呢&#xff1f; 单例模式在Python中的几种实现方…...

mysql数据库触发器同步数据

首先检查数据源库是否支持触发器&#xff0c;show ENGINES&#xff0c;如果FEDERATED是NO&#xff0c;表示未开启&#xff0c;如需开启&#xff0c;再mysql配置文件中&#xff0c;添加federated配置到mysqld下面。 一、同服务器不同库触发器同步&#xff0c;这里只举例插入数据…...

Prometheus-v2.45.0+Grafana+邮件告警

目录 普罗米修斯监控架构介绍 Prometheus 监控架构 1. 数据抓取&#xff08;Scraping&#xff09; 2. 时序数据库&#xff08;TSDB&#xff09; 3. 数据模型 4. PromQL 查询语言 5. 告警&#xff08;Alerting&#xff09; 6. Alertmanager 7. 可视化&#xff08;Visu…...

LeetCode——572. 另一颗树的子树

通过万岁&#xff01;&#xff01;&#xff01; 题目&#xff1a;给你两棵树&#xff0c;然后问subRoot是不是root的子树。也就是root某个节点的所有孩子节点在值和结构上完全与subRoot相同。思路&#xff1a;我的思路比较简单&#xff0c;就是遍历root&#xff0c;遇到root中…...