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

嵌入式Linux:信号掩码

在 Linux 系统中,内核为每一个进程维护了一个信号掩码(实际上是一个信号集),即一组信号的集合。当进程接收到一个在其信号掩码中定义的信号时,该信号将被阻塞,而不会立即传递给进程进行处理。这个阻塞行为意味着信号不会被丢弃,而是会被保留,直到该信号从信号掩码中移除,内核才会将其传递给进程进行处理。

向信号掩码中添加信号的三种方式:

  • 通过 signal()sigaction() 函数: 当应用程序调用 signal()sigaction() 函数为某一信号设置处理方式时,该信号通常会自动添加到进程的信号掩码中。这样做的目的是确保在处理某个信号时,如果该信号再次发生,它将被阻塞,以避免信号处理函数的重入问题。

    • 对于 sigaction() 函数来说,是否自动将信号添加到信号掩码中,还取决于是否设置了 SA_NODEFER 标志。如果设置了 SA_NODEFER,信号将不会被自动阻塞。
    • 当信号处理函数执行完毕并返回后,该信号将自动从信号掩码中移除,允许其再次传递。
  • 通过 sigaction()sa_mask 参数: 使用 sigaction() 为信号设置处理方式时,还可以通过 sa_mask 参数指定一组额外的信号。这些信号将在调用信号处理函数时被自动添加到信号掩码中,并在处理函数结束后移除。这种方式允许在处理某一信号时,临时阻塞其他相关的信号,以避免干扰。

  • 通过 sigprocmask() 系统调用: 除了上述两种方法,Linux 系统还提供了 sigprocmask() 系统调用,允许程序员在任何时候显式地向信号掩码中添加或移除信号。这种方法非常灵活,适用于需要精细控制信号屏蔽行为的场景。

本篇文章主要介绍sigprocmask() 函数向信号掩码中添加信号的方式。

sigprocmask() 的函数原型如下:

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • how 这个参数指定了对信号掩码的操作行为,有以下三种可能的值:

    • SIG_BLOCK:将 set 所指向的信号集中的所有信号添加到当前的信号掩码中(即将信号掩码设置为当前掩码与 set 的并集)。
    • SIG_UNBLOCK:从当前信号掩码中移除 set 所指向的信号集中的所有信号。
    • SIG_SETMASK:将当前的信号掩码直接设置为 set 所指向的信号集。
  • set 指向一个信号集,表示需要添加到(或移除自)信号掩码中的信号。如果 setNULL,则不改变当前的信号掩码。

  • oldset 如果 oldset 不为 NULL,则在修改信号掩码之前,会将当前的信号掩码保存到 oldset 指向的信号集中。这对于需要临时修改信号掩码并在之后恢复原来状态的操作非常有用。

  • 返回值: 如果调用成功,函数返回 0;如果失败,则返回 -1 并设置 errno 来指示错误原因。

以下代码展示了如何使用 sigprocmask() 将信号 SIGINT 添加到进程的信号掩码中,并在之后将其移除。

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>int main() {int ret;sigset_t sig_set;// 初始化信号集为空sigemptyset(&sig_set);// 向信号集中添加 SIGINT 信号sigaddset(&sig_set, SIGINT);// 将 SIGINT 添加到进程的信号掩码中(阻塞 SIGINT)ret = sigprocmask(SIG_BLOCK, &sig_set, NULL);if (ret == -1) {perror("sigprocmask error");exit(EXIT_FAILURE);}printf("SIGINT blocked\n");// 从信号掩码中移除 SIGINT 信号(解除阻塞)ret = sigprocmask(SIG_UNBLOCK, &sig_set, NULL);if (ret == -1) {perror("sigprocmask error");exit(EXIT_FAILURE);}printf("SIGINT unblocked\n");return 0;
}

信号掩码是 Linux 进程信号处理机制中的一个关键概念。通过 signal()sigaction()sigprocmask() 等函数,程序可以精确控制哪些信号应该被阻塞、哪些信号应该被传递。理解和灵活运用这些函数,可以帮助开发人员编写更加健壮的信号处理代码,避免信号干扰导致的潜在问题。


http://www.mrgr.cn/news/50816.html

相关文章:

  • windows系统备份mysql数据库bat脚本
  • 【基础解读】Word2Vec和GloVe
  • 注意力机制2024持续发力!多尺度卷积+Attention一举拿下高分!模型准确率几乎100%
  • 【自然语言处理】Encoder-Decoder架构
  • 100套深度学习毕业设计项目合集【含源码 + 操作文档】
  • 跨境电商干货:Etsy选品及相关运营技巧分享
  • SHELL脚本之输出语句的使用
  • 完全背包问题拓展(爬楼梯)
  • 【文件处理】一、XML格式文件处理
  • 大模型之三十二-语音合成TTS(coqui) 之二 fine-tune
  • STL源码剖析:适配器
  • 通过Express + Vue3从零构建一个用户认证与授权系统(二)数据库与后端项目搭建与实现
  • 【嵌入式】手把手教你入门STM32的GPIO:初识GPIO输出
  • [LeetCode 题3] 没有重复字符的最长的子字符串
  • 滚珠花键润滑技术优化:保障灵敏度与长寿命
  • 文件的读写、FileStream
  • 【基础篇】哨兵集群:哨兵挂了,主从库还能切换吗?
  • 101、QT摄像头录制视频问题
  • AI多模态测评基准(3):SuperCLUE-o 中文原生多模态实时交互测评基准
  • 4G、5G通信中,“网络侧“含义