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

【Linux探索学习】第二十八弹——信号(下):信号在内核中的处理及信号捕捉详解

Linux学习笔记:

https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482

前言:

在前面我们已经学习了有关信号的一些基本的知识点,包括:信号的概念、信号产生和信号处理等,今天我们重点来讲解一下信号在内核中的处理以及信号捕捉的相关知识点

在这篇文章中,我们将深入探讨 Linux 信号在内核中的处理流程,详细讲解信号递达、信号阻塞、未决信号、信号集操作、信号捕捉等内容,并通过大量的代码示例和实际场景来展示信号如何在 Linux 中运作。

与信号有关的还有一个很重要的知识点是有关用户态、内核态和状态切换的知识,本篇没有进行讲解,需要自己再去了解一下

目录

1. 信号在内核中的处理流程

1.1 信号在内核中的表示

1.2 信号的递达机制

信号递达的条件

信号递达过程

示例代码:信号递达

1.3 信号未决状态

信号未决队列的管理

示例代码:查看未决信号

1.4 信号集与 sigset_t

信号集的操作

示例代码:操作信号集

​编辑

1.5 信号屏蔽与 sigprocmask

示例代码:使用 sigprocmask() 阻塞和解除阻塞信号

1.6 获取未决信号:sigpending()

示例代码:使用 sigpending() 查看未决信号

2. 信号捕捉与处理

2.1 使用 signal() 捕捉信号

示例代码:使用 signal() 捕捉信号

2.2 使用 sigaction() 捕捉信号

示例代码:使用 sigaction() 捕捉信号

3. 总结


1. 信号在内核中的处理流程

信号是由内核或其他进程通过系统调用发送给目标进程的。当进程正在执行时,信号能够在不干扰进程当前操作的情况下打断它的执行,触发某种特定的行为。信号的处理流程在 Linux 内核中被设计得非常灵活,既支持异步信号处理,又能通过进程的信号屏蔽机制来控制信号的递达。

1.1 信号在内核中的表示

信号在内核中的表示示意图:

  • 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
  • SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
  • SIGOUIT信号未产生过,一旦产生SIGOUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。本章不讨论实时信号。

1.2 信号的递达机制

信号递达是信号机制中的核心概念,它是信号从信号源发送到目标进程的过程。信号递达的实现依赖于内核的进程调度机制。在进程执行过程中,内核需要判断该进程是否有需要处理的未决信号,信号的递达会在进程的上下文切换时被触发。

信号递达的条件

信号的递达取决于以下几个因素:

  1. 信号是否被屏蔽:每个进程都可以选择性地阻塞某些信号,当信号被阻塞时,它们会进入未决状态,直到信号被解除阻塞。
  2. 进程的当前状态:信号递达的时机还受进程状态的影响。如果进程处于不可中断的状态(例如执行系统调用),它可能无法立即处理信号,这时信号会被推迟递达,直到进程能够响应信号为止。
  3. 信号类型:标准信号和实时信号在递达的优先级上可能存在差异。实时信号(编号从 SIGRTMIN 开始)通常会比标准信号更快地递达,并且能够提供更多的控制选项。
信号递达过程

信号的递达过程通常包括以下几个步骤:

  1. 信号的发送:信号可以通过内核发送(例如内核事件或系统调用)或通过其他进程调用 kill() 函数发送。
  2. 信号的处理检查:当一个进程正在被调度执行时,内核会检查该进程是否有未决的信号。如果存在未决信号,内核会查看进程的信号屏蔽字,以决定这些信号是否可以递达。
  3. 信号的递送:如果信号未被屏蔽且能够递达,内核会根据进程的信号处理方式来决定是执行默认动作还是调用信号处理函数。
示例代码:信号递达
#include <stdio.h>
#include <signal.h>
#include <unistd.h>void signal_handler(int sig) {printf("Received signal: %d\n", sig);
}int main() {signal(SIGINT, signal_handler);  // 捕捉 SIGINT 信号printf("Waiting for SIGINT...\n");while(1) {sleep(1);  // 进入等待状态,直到接收到信号}return 0;
}

在上面的代码中,进程会一直运行并等待 SIGINT 信号(通常由按下 Ctrl+C 触发)。一旦进程接收到 SIGINT 信号,内核会将其递送到进程,并触发信号处理函数 signal_handler

1.3 信号未决状态

当信号发送给进程时,如果该信号被进程的信号屏蔽字阻塞,那么该信号就会进入未决状态。未决信号是那些已经被发送但尚未被递达的信号。内核维护了每个进程的未决信号队列,并会在进程解除对该信号的阻塞时按顺序递送这些信号。

信号未决队列的管理

在 Linux 内核中,每个进程都有一个 task_struct 结构体,其中包含了当前进程的未决信号集合。每当一个信号发送给一个进程时,如果该信号被阻塞,内核不会立即递送它,而是将其存放在进程的未决信号队列中,直到进程解除对该信号的阻塞。

未决信号通常在进程解除信号屏蔽字后,由内核递送。递送顺序通常与信号发送顺序一致,且会按照优先级递送实时信号和标准信号。

示例代码:查看未决信号
#include <stdio.h>
#include <signal.h>
#include <unistd.h>int main() {sigset_t pending;sigpending(&pending);  // 获取当前进程的未决信号if (sigismember(&pending, SIGINT)) {printf("SIGINT is pending.\n");} else {printf("No SIGINT pending.\n");}sleep(10);  // 稍作停顿,方便查看信号状态return 0;
}

通过使用 sigpending() 函数,我们可以查看当前进程的未决信号集。如果进程没有处理 SIGINT 信号,且信号被阻塞,则该信号会处于未决状态。

1.4 信号集与 sigset_t

信号集(sigset_t)是一个用于表示信号集合的数据结构,它通过位掩码的方式表示进程当前可以接受的信号集合。sigset_t 通常是一个整数或更大的数据类型,每一位对应一个信号。

信号集的操作

在 Linux 中,常用的信号集操作函数包括:

  • sigemptyset():初始化信号集为空集。
  • sigaddset():将某个信号添加到信号集中。
  • sigdelset():将某个信号从信号集中删除。
  • sigismember():判断某个信号是否在信号集中。
示例代码:操作信号集
#include <signal.h>
#include <stdio.h>int main() {sigset_t set;sigemptyset(&set);         // 初始化为空集sigaddset(&set, SIGINT);   // 将 SIGINT 添加到信号集中sigaddset(&set, SIGTERM);  // 将 SIGTERM 添加到信号集中if (sigismember(&set, SIGINT)) {printf("SIGINT is in the set.\n");}sigdelset(&set, SIGINT);   // 从信号集中删除 SIGINTif (!sigismember(&set, SIGINT)) {printf("SIGINT is no longer in the set.\n");}return 0;
}

1.5 信号屏蔽与 sigprocmask

sigprocmask() 是一个用于修改进程信号屏蔽字的系统调用,它可以用来阻塞、解除阻塞或查询进程的信号屏蔽字。信号屏蔽字定义了哪些信号是被阻塞的,从而影响信号递达的时机。

sigprocmask() 具有以下操作模式:

  • SIG_BLOCK:将指定的信号添加到信号屏蔽字中,阻塞这些信号。
  • SIG_UNBLOCK:从信号屏蔽字中删除指定信号,解除阻塞。
  • SIG_SETMASK:将信号屏蔽字设置为指定值,替换当前的信号屏蔽字。
示例代码:使用 sigprocmask() 阻塞和解除阻塞信号
#include <signal.h>
#include <stdio.h>
#include<unistd.h>int main() {sigset_t new_mask, old_mask;sigemptyset(&new_mask);sigaddset(&new_mask, SIGINT);  // 阻塞 SIGINTsigprocmask(SIG_BLOCK, &new_mask, &old_mask);  // 阻塞 SIGINT// 信号屏蔽后,可以进行一些操作printf("SIGINT is blocked. Press Ctrl+C to send SIGINT.\n");sleep(10);  // 暂停,等待 Ctrl+C 输入// 恢复信号屏蔽字sigprocmask(SIG_SETMASK, &old_mask, NULL);  // 恢复原信号屏蔽字printf("SIGINT is unblocked.\n");sleep(10);  // 等待信号递达return 0;
}

在这段代码中,SIGINT 信号在前 10 秒内被阻塞,用户按下 Ctrl+C 时信号不会立即递达。10 秒后,信号屏蔽被解除,SIGINT 信号会被递送并触发相应的处理。

1.6 获取未决信号:sigpending()

sigpending() 函数用于获取当前进程的未决信号,它返回一个信号集,表示该进程尚未处理的信号集合。sigpending() 的实现依赖于进程的信号队列,它可以用于调试和监控进程的信号处理状态。

示例代码:使用 sigpending() 查看未决信号
#include <signal.h>
#include <stdio.h>
#include <unistd.h>int main() {sigset_t pending;sigemptyset(&pending);// 阻塞 SIGINT 信号sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGINT);sigprocmask(SIG_BLOCK, &mask, NULL);// 发送 SIGINT 信号,但它会被阻塞kill(getpid(), SIGINT);// 获取未决信号sigpending(&pending);if (sigismember(&pending, SIGINT)) {printf("SIGINT is pending.\n");} else {printf("No SIGINT pending.\n");}sleep(5);  // 稍作等待,防止信号丢失return 0;
}

此程序模拟了阻塞 SIGINT 信号并通过 sigpending() 查看进程的未决信号状态。如果信号被阻塞,它将在信号屏蔽字解除后递达。


2. 信号捕捉与处理

信号捕捉是指进程通过自定义信号处理函数来响应特定的信号。Linux 提供了 signal()sigaction() 两种方式来捕捉信号。signal() 是一种简单的接口,而 sigaction() 提供了更为复杂的配置选项,使得开发者能够在处理信号时获得更多的控制权。

2.1 使用 signal() 捕捉信号

signal() 是最基础的信号捕捉方式,它允许开发者指定一个信号处理函数来响应特定信号。signal() 的使用非常简单,但它并不支持所有高级功能,如信号的重入处理或复杂的信号控制。

示例代码:使用 signal() 捕捉信号
#include <signal.h>
#include <stdio.h>
#include<unistd.h>void signal_handler(int sig) {printf("Received signal: %d\n", sig);
}int main() {signal(SIGINT, signal_handler);  // 捕捉 SIGINT 信号printf("Waiting for SIGINT...\n");while (1) {sleep(1);  // 程序将一直运行,直到接收到信号}return 0;
}

在这个示例中,signal_handler 函数会在接收到 SIGINT 信号时被调用。

2.2 使用 sigaction() 捕捉信号

sigaction() 提供了比 signal() 更灵活的方式来处理信号。它允许开发者在捕捉信号时设定更多的参数,比如如何处理重入信号、是否需要恢复默认行为等。

sigaction() 的结构体定义如下:

struct sigaction {void (*sa_handler)(int);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);
};
  • sa_handler:指定信号处理函数。
  • sa_mask:指定在信号处理期间需要阻塞的信号集。
  • sa_flags:设定信号处理的行为。
示例代码:使用 sigaction() 捕捉信号
#include <signal.h>
#include <stdio.h>
#include<unistd.h>void signal_handler(int sig) {printf("Received signal: %d\n", sig);
}int main() {struct sigaction sa;sa.sa_handler = signal_handler;  // 指定信号处理函数sa.sa_flags = 0;sigemptyset(&sa.sa_mask);  // 初始化信号集sigaction(SIGINT, &sa, NULL);  // 捕捉 SIGINT 信号printf("Waiting for SIGINT...\n");while (1) {sleep(1);  // 程序将一直运行,直到接收到信号}return 0;
}

通过 sigaction(),程序能够灵活地处理信号,并控制信号捕捉的行为,甚至允许在处理信号时阻塞其他信号。

3. 总结

本文我们讲解了信号的处理机制,并且对信号捕捉进行了更详细的补充,结合上篇内容,基本上将信号部分的内容进行了大概的讲解,认真看一下相信会对你有所帮助

感谢各位大佬观看,创作不易,还望各位大佬点赞支持!!!

相关文章:

【Linux探索学习】第二十八弹——信号(下):信号在内核中的处理及信号捕捉详解

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在前面我们已经学习了有关信号的一些基本的知识点&#xff0c;包括&#xff1a;信号的概念、信号产生和信号处理等&#xff0c;今天我们重…...

AI与SEO关键词的完美结合如何提升网站流量与排名策略

内容概要 在当今数字营销环境中&#xff0c;内容的成功不仅依赖于高质量的创作&#xff0c;还包括高效的关键词策略。AI与SEO关键词的结合&#xff0c;正是这一趋势的重要体现。 AI技术在SEO中的重要性 在数字营销领域&#xff0c;AI技术的引入为SEO策略带来了前所未有的变革。…...

《运维:技术的基石,服务的保障》

1. LVS&#xff08;Linux Virtual Server&#xff09;&#xff1a;基于Linux内核的四层负载均衡解决方案 2. Bonding&#xff08;链路聚合&#xff09;&#xff1a;物理网卡冗余与带宽叠加技术 3. RHEL&#xff08;Red Hat Enterprise Linux&#xff09;&#xff1a;企业级Li…...

CSS Display属性完全指南

CSS Display属性完全指南 引言核心概念常用display值详解1. block&#xff08;块级元素&#xff09;2. inline&#xff08;行内元素&#xff09;3. inline-block&#xff08;行内块级元素&#xff09;4. flex&#xff08;弹性布局&#xff09;5. grid&#xff08;网格布局&…...

【C++】STL——vector底层实现

目录 &#x1f495; 1.vector三个核心 &#x1f495;2.begin函数&#xff0c;end函数的实现&#xff08;简单略讲&#xff09; &#x1f495;3.size函数&#xff0c;capacity函数的实现 &#xff08;简单略讲&#xff09; &#x1f495;4.reserve函数实现 &#xff08;细节…...

Docker Compose的使用

文章首发于我的博客&#xff1a;https://blog.liuzijian.com/post/docker-compose.html 目录 Docker Compose是什么Docker Compose安装Docker Compose文件Docker Compose常用命令案例&#xff1a;部署WordPress博客系统 Docker Compose是什么 Docker Compose是Docker官方的开源…...

11 3D变换模块(transform3d.rs)

transform3d.rs代码定义了一个名为 Transform3D 的 Rust 结构体&#xff0c;它用于表示一个3D变换矩阵。这个结构体是泛型的&#xff0c;包含三个类型参数&#xff1a;T、Src 和 Dst。其中&#xff0c;T 用于矩阵元素的数据类型&#xff0c;Src 和 Dst 用于表示变换的源和目标类…...

昆仑万维Java开发面试题及参考答案

进程和线程的区别是什么? 进程和线程都是操作系统中非常重要的概念,它们在多个方面存在显著的区别。 从定义上看,进程是操作系统进行资源分配和调度的基本单位。每个进程都有自己独立的内存空间,包括代码段、数据段、堆栈段等。例如,当你在电脑上同时打开浏览器和音乐播放…...

vscode命令面板输入 CMake:build不执行提示输入

CMake&#xff1a;build或rebuild不编译了&#xff0c;弹出:> [Add a new preset] , 提示输入发现settings.jsons设置有问题 { "workbench.colorTheme": "Default Light", "cmake.pinnedCommands": [ "workbench.action.tasks.configu…...

Fastdds学习分享_xtpes_发布订阅模式及rpc模式

在之前的博客中我们介绍了dds的大致功能&#xff0c;与组成结构。本篇博文主要介绍的是xtypes.分为理论和实际运用两部分.理论主要用于梳理hzy大佬的知识&#xff0c;对于某些一带而过的部分作出更为详细的阐释&#xff0c;并在之后通过实际案例便于理解。案例分为普通发布订阅…...

什么叫DeepSeek-V3,以及与GPT-4o的区别

1. DeepSeek 的故事 1.1 DeepSeek 是什么&#xff1f; DeepSeek 是一家专注于人工智能技术研发的公司&#xff0c;致力于打造高性能、低成本的 AI 模型。它的目标是让 AI 技术更加普惠&#xff0c;让更多人能够用上强大的 AI 工具。 1.2 DeepSeek-V3 的问世 DeepSeek-V3 是…...

【C#】Process、ProcessStartInfo启动外部exe

在C#中使用 Process 和 ProcessStartInfo 类启动外部 .exe 文件&#xff0c;可以按照以下步骤进行&#xff1a; 创建 ProcessStartInfo 实例&#xff1a;配置进程启动信息&#xff0c;包括可执行文件的路径、传递给该程序的参数等。 设置启动选项&#xff1a;根据需要配置 Pro…...

android 音视频系列引导

音视频这块的知识点自己工作中有用到&#xff0c;一直没有好好做一个总结&#xff0c;原因有客观和主观的。 客观是工作太忙&#xff0c;没有成段时间做总结。 主观自己懒。 趁着这次主动离职拿了n1的钱&#xff0c;休息一下&#xff0c;对自己的人生做一下总结&#xff0c;…...

Mac电脑上最新的好用邮件软件比较

在Mac电脑上&#xff0c;选择一款好用的邮件软件需要根据个人需求、功能偏好以及与系统生态的兼容性来决定。以下是基于我搜索到的资料&#xff0c;对当前市场上一些优秀的邮件客户端进行比较和推荐&#xff1a; 1. Apple Mail Apple Mail是Mac系统自带的邮件客户端&#xff…...

C#,入门教程(11)——枚举(Enum)的基础知识和高级应用

上一篇&#xff1a; C#&#xff0c;入门教程(10)——常量、变量与命名规则的基础知识https://blog.csdn.net/beijinghorn/article/details/123913570 不会枚举&#xff0c;就不会编程&#xff01; 枚举 一个有组织的常量系列 比如&#xff1a;一个星期每一天的名字&#xf…...

Spring 实现注入的方式

一、XML配置文件注入 概念&#xff1a;这是一种传统的依赖注入方式&#xff0c;通过在XML文件中配置bean的相关信息来实现依赖注入。在Spring框架中&#xff0c;需要在applicationContext.xml或spring-config.xml等配置文件中定义bean&#xff0c;并通过<property>标签或…...

【论文复现】粘菌算法在最优经济排放调度中的发展与应用

目录 1.摘要2.黏菌算法SMA原理3.改进策略4.结果展示5.参考文献6.代码获取 1.摘要 本文提出了一种改进粘菌算法&#xff08;ISMA&#xff09;&#xff0c;并将其应用于考虑阀点效应的单目标和双目标经济与排放调度&#xff08;EED&#xff09;问题。为提升传统粘菌算法&#xf…...

【LLM-agent】(task6)构建教程编写智能体

note 构建教程编写智能体 文章目录 note一、功能需求二、相关代码&#xff08;1&#xff09;定义生成教程的目录 Action 类&#xff08;2&#xff09;定义生成教程内容的 Action 类&#xff08;3&#xff09;定义教程编写智能体&#xff08;4&#xff09;交互式操作调用教程编…...

04树 + 堆 + 优先队列 + 图(D1_树(D10_决策树))

目录 一、引言 二、算法原理 三、算法实现 四、知识小结 一、引言 决策树算法是一种常用的机器学习算法&#xff0c;可用于分类和回归问题。它基于特征之间的条件判断来构 建一棵树&#xff0c;树的每个节点代表一个特征&#xff0c;每个叶节点代表一个类别或回归值。决策…...

JavaScript模块化

什么是JavaScript的模块化&#xff1f; JavaScript的模块化是指将代码分割成独立的、可重用的模块&#xff0c;每个模块具有自己的功能和作用&#xff0c;可以单独进行开发、测试和维护。不同的目的是提升代码的可维护性、可复用性和可扩展性&#xff0c;同时避免不同模块间的…...

排序算法--插入排序

插入排序是一种简单且稳定的排序算法&#xff0c;适合小规模数据或部分有序数据。 // 插入排序函数 void insertionSort(int arr[], int n) {for (int i 1; i < n; i) { // 从第二个元素开始int key arr[i]; // 当前需要插入的元素int j i - 1;// 将比 key 大的元素向后移…...

【C语言篇】“三子棋”

一、游戏介绍 三子棋&#xff0c;英文名为 Tic - Tac - Toe&#xff0c;是一款简单而经典的棋类游戏。游戏在一个 33 的棋盘上进行&#xff0c;两名玩家轮流在棋盘的空位上放置自己的棋子&#xff08;通常用 * 和 # 表示&#xff09;&#xff0c;率先在横、竖或斜方向上连成三个…...

【大模型理论篇】DeepSeek-R1:引入冷启动的强化学习

1. 背景 首先给出DeepSeek-V3、DeepSeek-R1-Zero、DeepSeek-R1的关系图【1】。 虽然DeepSeek-R1-Zero推理能力很强&#xff0c;但它也面临一些问题。例如&#xff0c;DeepSeek-R1-Zero存在可读性差和语言混杂等问题。为了使推理过程更具可读性&#xff0c;进而推出了DeepSee…...

Linux基础 ——tmux vim 以及基本的shell语法

Linux 基础 ACWING y总的Linux基础课&#xff0c;看讲义作作笔记。 tmux tmux 可以干嘛&#xff1f; tmux可以分屏多开窗口&#xff0c;可以进行多个任务&#xff0c;断线&#xff0c;不会自动杀掉正在进行的进程。 tmux – session(会话&#xff0c;多个) – window(多个…...

使用 Kotlin 将 Vertx 和 Springboot 整合

本篇文章目的是将 Springboot 和 Vertx 进行简单整合。整合目的仅仅是为了整活&#xff0c;因为两个不同的东西整合在一起提升的性能并没有只使用 Vertx 性能高&#xff0c;因此追求高性能的话这是在我来说不推荐。而且他们不仅没有提高很多性能甚至增加了学习成本 一、整合流…...

【单层神经网络】softmax回归的从零开始实现(图像分类)

softmax回归 该回归分析为后续的多层感知机做铺垫 基本概念 softmax回归用于离散模型预测&#xff08;分类问题&#xff0c;含标签&#xff09; softmax运算本质上是对网络的多个输出进行了归一化&#xff0c;使结果有一个统一的判断标准&#xff0c;不必纠结为什么要这么算…...

课题推荐——基于自适应滤波技术的多传感器融合在无人机组合导航中的应用研究

无人机在现代航空、农业和监测等领域的应用日益广泛。为了提高导航精度&#xff0c;通常采用多传感器融合技术&#xff0c;将来自GPS、惯性测量单元&#xff08;IMU&#xff09;、磁力计等不同传感器的数据整合。然而&#xff0c;传感器的量测偏差、环境干扰以及非线性特性使得…...

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户登录

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【Spring篇】【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;1.登录-持久层 &…...

Mono里运行C#脚本40—mono_magic_trampoline函数的参数设置

前面介绍过跳板代码,它是用来切换托管代码与非托管的代码,以及运行时与C#代码的交互。实现从运行时切换到C#代码来运行,再从C#代码返回运行时。 要想理解整个切换的细节,那么就需要理解mono_magic_trampoline函数, 而要理解此函数,就必须了解这个函数的参数来源。 要理…...

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的,所以任何电路都可以表示为模块和赋值语句的某种组合. 然而,有时这不是描述电路最方便的方法. 两种always block是十分有用的: 组合逻辑: always @(…...

实际操作 检测缺陷刀片

号he 找到目标图像的缺陷位置&#xff0c;首先思路为对图像进行预处理&#xff0c;灰度-二值化-针对图像进行轮廓分析 //定义结构元素 Mat se getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); morphologyEx(thre, tc, MORPH_OPEN, se, Point(-1, -1), 1); …...

DeepSeek 阐述 2025年前端发展趋势

预测2025年前端的发展趋势。首先&#xff0c;我需要考虑当前的前端 技术发展情况&#xff0c;以及近几年的变化趋势。比如&#xff0c;框架方面&#xff0c;React、Vue、Angular这些主流框架的更新方向和社区活跃度。可能用户想知道未来哪些技术会更流行&#xff0c;或者需要学…...

Elasticsearch基本使用详解

文章目录 Elasticsearch基本使用详解一、引言二、环境搭建1、安装 Elasticsearch2、安装 Kibana&#xff08;可选&#xff09; 三、索引操作1、创建索引2、查看索引3、删除索引 四、数据操作1、插入数据2、查询数据&#xff08;1&#xff09;简单查询&#xff08;2&#xff09;…...

【Rust自学】17.3. 实现面向对象的设计模式

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 17.3.1. 状态模式 状态模式(state pattern) 是一种面向对象设计模式&#xff0c;指的是一个值拥有的内部状态由数个状态对象&#xff08…...

司库建设-融资需求分析与计划制定

当企业现金流紧张时&#xff0c;企业需要考虑外部融资&#xff0c;从财务营运角度来考虑和分析如何确定输入和输出&#xff0c;进行整体解决方案设计。 融资需求分析与计划制定 功能点&#xff1a; 现金流预测工具&#xff1a;集成历史数据和业务计划&#xff0c;自动生成未来1…...

2. 【.NET Aspire 从入门到实战】--理论入门与环境搭建--.NET Aspire 概览

在当今快速发展的软件开发领域&#xff0c;构建高效、可靠且易于维护的云原生应用程序已成为开发者和企业的核心需求。.NET Aspire 作为一款专为云原生应用设计的开发框架&#xff0c;旨在简化分布式系统的构建和管理&#xff0c;提供了一整套工具、模板和集成包&#xff0c;帮…...

【Elasticsearch】allow_no_indices

- **allow_no_indices 参数的作用**&#xff1a; 该参数用于控制当请求的目标索引&#xff08;通过通配符、别名或 _all 指定&#xff09;不存在或已关闭时&#xff0c;Elasticsearch 的行为。 - **默认行为**&#xff1a; 如果未显式设置该参数&#xff0c;默认值为 …...

26.useScript

在 Web 应用开发中&#xff0c;动态加载外部脚本是一个常见需求&#xff0c;特别是在需要集成第三方库或服务时。然而&#xff0c;在 React 应用中管理脚本加载可能会变得复杂。useScript 钩子提供了一种优雅的方式来处理外部脚本的加载、错误处理和清理&#xff0c;使得在 Rea…...

跨域问题和解决方案

跨域问题及解决方案 同源策略及跨域问题 同源策略是一套浏览器安全机制&#xff0c;当一个源的文档和脚本&#xff0c;与另一个源的资源进行通信时&#xff0c;同源策略就会对这个通信做出不同程度的限制。 简单来说&#xff0c;同源策略对 同源资源 放行&#xff0c;对 异源…...

springboot中路径默认配置与重定向/转发所存在的域对象

Spring Boot 是一种简化 Spring 应用开发的框架&#xff0c;它提供了多种默认配置和方便的开发特性。在 Web 开发中&#xff0c;路径配置和请求的重定向/转发是常见操作。本文将详细介绍 Spring Boot 中的路径默认配置&#xff0c;并解释重定向和转发过程中存在的域对象。 一、…...

【OS】AUTOSAR架构下的Interrupt详解(下篇)

目录 3.代码分析 3.1中断配置代码 3.2 OS如何找到中断处理函数 3.3 Os_InitialEnableInterruptSources实现 3.4 Os_EnableInterruptSource 3.5 DisableAllInterrupts 3.5.1Os_IntSuspendCat1 3.5.2 Os_InterruptDisableAllEnter 3.5.3 Disable二类中断 3.5.4 Disable一…...

基于遗传算法的256QAM星座图的最优概率整形matlab仿真,对比优化前后整形星座图和误码率

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; GA优化曲线&#xff1a; 优化前后星座图对比 优化前后误码率对比 仿真操作步骤…...

Android学习21 -- launcher

1 前言 之前在工作中&#xff0c;第一次听到launcher有点蒙圈&#xff0c;不知道是啥&#xff0c;当时还赶鸭子上架去和客户PK launcher的事。后来才知道其实就是安卓的桌面。本来还以为很复杂&#xff0c;毕竟之前接触过windows的桌面&#xff0c;那叫一个复杂。。。 后面查了…...

小程序越来越智能化,作为设计师要如何进行创新设计

一、用户体验至上 &#xff08;一&#xff09;简洁高效的界面设计 小程序的特点之一是轻便快捷&#xff0c;用户期望能够在最短的时间内找到所需功能并完成操作。因此&#xff0c;设计师应致力于打造简洁高效的界面。避免过多的装饰元素和复杂的布局&#xff0c;采用清晰的导航…...

【实践案例】基于大语言模型的海龟汤游戏

文章目录 项目背景提示词构建海龟汤主持人真相判断专家 具体实现流程文心一言大语言模型“海龟汤”插件参考 项目背景 “海龟汤”作为一种聚会类桌游&#xff0c;又称情境推理游戏&#xff0c;是一种猜测情境还原事件真相的智力游戏。其玩法是由出题者提出一个难以理解的事件&…...

基于多智能体强化学习的医疗AI中RAG系统程序架构优化研究

一、引言 1.1 研究背景与意义 在数智化医疗飞速发展的当下,医疗人工智能(AI)已成为提升医疗服务质量、优化医疗流程以及推动医学研究进步的关键力量。医疗 AI 借助机器学习、深度学习等先进技术,能够处理和分析海量的医疗数据,从而辅助医生进行疾病诊断、制定治疗方案以…...

【Unity2D 2022:UI】创建滚动视图

一、创建Scroll View游戏对象 在Canvas画布下新建Scroll View游戏对象 二、为Content游戏对象添加Grid Layout Group&#xff08;网格布局组&#xff09;组件 选中Content游戏物体&#xff0c;点击Add Competent添加组件&#xff0c;搜索Grid Layout Group组件 三、调整Grid La…...

C++ Primer 多维数组

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…...

怀旧经典:1200+款红白机游戏合集,Windows版一键畅玩

​沉浸在怀旧的海洋中&#xff0c;体验经典红白机游戏的魅力&#xff01;我们为您精心准备了超过1200款经典游戏的合集&#xff0c;每一款都是时代的印记&#xff0c;每一场都是回忆的旅程。这个合集不仅包含了丰富的游戏资源&#xff0c;还内置了多个Windows版的NES模拟器&…...

【数据采集】案例02:基于Selenium采集豆瓣电影Top250的详细数据

基于Selenium采集豆瓣电影Top250的详细数据 Selenium官网:https://www.selenium.dev/blog/ 豆瓣电影Top250官网:https://movie.douban.com/top250 写在前面 实验目标:基于Selenium框架采集豆瓣电影Top250的详细数据。 电脑系统:Windows 使用软件:PyCharm、Navicat 技术需求…...