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

Linux 信号控制

目录

一、背景:为什么要研究信号屏蔽与未决信号?

二、代码拆解:从示例看核心逻辑

1. 信号集的初始化与屏蔽设置

2. 未决信号的查询与打印

三、关键问题解答:穿透代码看本质

问题 1:“我可以将所有的信号都进行屏蔽,信号不就不会被处理了吗?”

问题 2:“sigset_t 是在哪里开辟的空间?”

问题 3:“未决信号的本质是什么?”

四、扩展:信号屏蔽与未决的典型应用场景

场景 1:关键逻辑的 “原子性” 保障

场景 2:批量处理未决信号

五、总结


在 Linux 系统编程中,信号是进程间通信和系统事件通知的重要机制。今天我们就以一段关于 ** 信号屏蔽(sigprocmask)未决信号(sigpending)** 的代码为切入点,深入剖析这两个概念的底层逻辑与实际应用。

一、背景:为什么要研究信号屏蔽与未决信号?

在多任务、多事件的系统环境中,进程可能会同时收到多个信号。但有些场景下,我们希望暂时屏蔽某些信号(比如在执行关键逻辑时,不希望被干扰);同时,我们也需要知道有哪些信号被屏蔽后处于 “待处理” 状态(即未决信号)。这两个机制 ——sigprocmasksigpending,就是用来解决这些问题的关键工具。

二、代码拆解:从示例看核心逻辑

先看我们的示例代码,它主要做了两件事:屏蔽所有 1-31 号信号,并循环打印当前的未决信号集合

1. 信号集的初始化与屏蔽设置

运行

sigset_t bset, oset;
sigemptyset(&bset);
sigemptyset(&oset);
for (int i = 1; i <= 31; i++)
{sigaddset(&bset, i); // 将1-31号信号加入屏蔽集
}
sigprocmask(SIG_SETMASK, &bset, &oset);
  • sigset_t:是 Linux 中用于表示信号集合的数据结构,本质上是一个位图(每一位对应一个信号)。
  • sigemptyset:初始化一个空的信号集合(所有位设为 0)。
  • sigaddset:将指定信号加入集合(对应位设为 1)。
  • sigprocmask核心系统调用,用于修改进程的信号屏蔽字(即进程当前屏蔽哪些信号)。SIG_SETMASK表示用bset完全替换当前的屏蔽字,oset用于保存旧的屏蔽字(以便后续恢复)。

2. 未决信号的查询与打印

运行

sigset_t pending;
while (true)
{int n = sigpending(&pending); // 获取当前进程的未决信号集合if (n < 0)continue;PrintPending(pending); // 打印未决信号的位图sleep(1);
}void PrintPending(sigset_t &pending)
{for (int signo = 31; signo >= 1; signo--){if (sigismember(&pending, signo)) // 判断信号是否在未决集合中cout << "1";elsecout << "0";}cout << "\n\n";
}
  • sigpending:获取进程的未决信号集合(即被屏蔽且已经发送到进程,但尚未被处理的信号)。
  • sigismember:判断某个信号是否在信号集合中。
  • 打印逻辑:从 31 号到 1 号信号依次判断,输出 “1” 表示该信号未决,“0” 表示未未决,这样就能直观看到未决信号的位图状态。

三、关键问题解答:穿透代码看本质

问题 1:“我可以将所有的信号都进行屏蔽,信号不就不会被处理了吗?”

回答:大部分信号会被屏蔽,但有例外!

在 Linux 中,9号信号(SIGKILL)19号信号(SIGSTOP)不可屏蔽的。这是系统级的安全设计 —— 比如SIGKILL用于强制终止进程,若能被屏蔽,进程就可能无法被杀死,导致系统资源泄漏;SIGSTOP用于暂停进程,同理需要保证其强制性。

所以,即使代码中尝试屏蔽所有 1-31 号信号,SIGKILLSIGSTOP仍然可以突破屏蔽,作用于进程。

问题 2:“sigset_t 是在哪里开辟的空间?”

回答:在用户栈上,属于进程的用户空间。

sigset_t bset, oset;是在main函数中定义的局部变量,因此存储在进程的用户栈中(属于用户空间内存)。当调用sigprocmask时,内核会读取用户空间中bset的值,进而修改内核中进程task_struct里的信号屏蔽字。

问题 3:“未决信号的本质是什么?”

回答:未决信号是 “被屏蔽且已送达” 的信号的临时存储。

每个进程的task_struct中,有一个未决信号集合(pending)和一个信号屏蔽字(mask)。当一个信号被发送到进程时:

  • 若该信号未被屏蔽(mask 中对应位为 0),则进程会立即处理(执行默认动作或自定义处理器);
  • 若该信号被屏蔽(mask 中对应位为 1),则会被记录到未决集合(pending 中对应位置 1),直到屏蔽被解除,才会被处理。

四、扩展:信号屏蔽与未决的典型应用场景

场景 1:关键逻辑的 “原子性” 保障

在执行一段不希望被信号打断的关键逻辑时(比如数据库事务、文件写入的关键步骤),可以先屏蔽信号,执行完逻辑后再解除屏蔽:

运行

sigset_t oldmask, newmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT); // 屏蔽Ctrl+C信号(2号)sigprocmask(SIG_BLOCK, &newmask, &oldmask); // 保存旧屏蔽字,屏蔽SIGINT// 执行关键逻辑...sigprocmask(SIG_SETMASK, &oldmask, NULL); // 恢复旧屏蔽字,解除SIGINT屏蔽

场景 2:批量处理未决信号

有时我们希望 “积攒” 一批信号,然后一次性处理。可以先屏蔽信号,等业务逻辑完成后,查询未决信号并逐个处理:

运行

// 屏蔽信号
sigset_t mask, oldmask;
sigfillset(&mask); // 填充所有信号(除不可屏蔽的)
sigprocmask(SIG_SETMASK, &mask, &oldmask);// 执行业务逻辑,期间收到的信号会进入未决状态...// 查询并处理未决信号
sigset_t pending;
sigpending(&pending);
for (int signo = 1; signo <= 31; signo++)
{if (sigismember(&pending, signo)){cout << "处理未决信号:" << signo << endl;// 这里可以调用信号处理函数}
}// 恢复屏蔽字
sigprocmask(SIG_SETMASK, &oldmask, NULL);

五、总结

通过这段代码和对原理的剖析,我们可以清晰地理解:

  • sigprocmask是进程 “主动控制哪些信号可以打扰自己” 的工具;
  • sigpending是进程 “查看有哪些被屏蔽的信号在排队等待处理” 的窗口;
  • 信号屏蔽与未决机制,是 Linux 系统中进程对信号 “精细管控” 的核心手段,在系统编程、服务器开发等场景中有着广泛应用。

希望这篇博客能帮大家穿透代码,真正理解信号屏蔽与未决的底层逻辑~

http://www.dtcms.com/a/515713.html

相关文章:

  • Android Studio模拟器无法联网(能打开IP网页,但不能打开域名,DNS解析错误)问题2025年10月22日
  • php如何做局域网的网站网站设计与网页制作代码大全
  • 在没有网络的环境下安装包pymysql
  • Gradle 构建脚本迁移:从 Groovy DSL 到 Kotlin DSL,语法与技巧对比
  • 个人网站审批怎么制作ppt模板 教程
  • 内网构建https
  • [运维]宝塔 Apache环境使用CDN获取访客真实IP方法
  • 【学习系列】SAP RAP 17:RAP应用部署集成至Fiori Launchpad 【S4HC Public Edition】
  • 正点原子RK3568学习日志15-杂项设备驱动
  • 绍兴建设开发有限公司网站网站网站娱乐建设
  • 迭代器失效问题
  • Ubuntu 16.04交叉编译arm-linux-gnueabihf的QT5.6.2
  • 神经网络详解
  • 网站如何防止黑客攻击宁波新闻
  • 为打印预览对话框 PrintPreviewDialog 添加保存到 PDF 文件按钮源代码详解
  • Nevercenter CameraBag Photo for mac照片滤镜美化软件
  • 设计模式-策略模式:从鞋厂促销活动看算法的灵活切换
  • Java实现Excel转PDF
  • Fenwick 树进行快速统计
  • Cocos creator2.4.4 处理 16KB 问题
  • 旅游网站的设计的前提成都那家网站做的好
  • undefined reference to `cv::String::dea llocate()‘
  • 计划任务原理及实战
  • 做网站设计最好的公司做旅游网站的论文
  • 【Android】Handler/Looper机制相关的类图和流程图
  • ARM《1》_回顾gcc、动态编译和静态编译、MakeFile的使用
  • 网络环路:隐形威胁的破解之道
  • stm32 can错误中断不处理
  • 我们平常说的连网是指什么?
  • 网站优化人员新乡市延津县建设局网站