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

企业网站模板seo公益建设网站的作用

企业网站模板seo,公益建设网站的作用,合肥房产,国家企业信用公示信息网官网sigprocmask 函数深度解析 sigprocmask 是 Linux 信号处理的核心函数,用于控制进程的信号屏蔽字(Signal Mask)。它直接决定了哪些信号会被阻塞(blocked),是构建可靠信号处理机制的基础。函数原型 #include …

sigprocmask 函数深度解析

sigprocmask 是 Linux 信号处理的核心函数,用于控制进程的信号屏蔽字(Signal Mask)。它直接决定了哪些信号会被阻塞(blocked),是构建可靠信号处理机制的基础。


函数原型

#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数详解

1. how:操作类型(行为模式)
宏定义值含义数学表达
SIG_BLOCK0set 中的信号添加到当前屏蔽字新掩码 = 当前掩码 ∪ set
SIG_UNBLOCK1set 中的信号移除出当前屏蔽字新掩码 = 当前掩码 - set
SIG_SETMASK2将当前屏蔽字直接替换set 指定的信号集新掩码 = set

⚠️ 非法值处理:如果 how 不是以上三个值,函数返回 -1 并设置 errno = EINVAL

2. set:输入信号集指针
含义
非NULL指向包含操作信号的 sigset_t 对象,具体操作由 how 决定
NULL不改变当前屏蔽字(此时 how 被忽略),仅用于获取当前屏蔽字到 oldset
3. oldset:输出信号集指针
含义
非NULL函数将在此存储修改前的信号屏蔽字
NULL不保存之前的屏蔽字

返回值

含义
0成功
-1失败,设置 errno

错误码(errno)

错误码含义常见触发场景
EFAULT无效的内存地址setoldset 指向非法地址
EINVAL无效的 how 参数how 不是 SIG_BLOCK/UNBLOCK/SETMASK

核心功能图解

SIG_BLOCK
SIG_UNBLOCK
SIG_SETMASK
调用 sigprocmask
how 类型?
新屏蔽字 = 当前屏蔽字 OR set
新屏蔽字 = 当前屏蔽字 AND NOT set
新屏蔽字 = set
oldset 非空?
保存旧屏蔽字到 oldset
完成

使用场景详解

场景1:阻塞特定信号(SIG_BLOCK)
sigset_t new_set;
sigemptyset(&new_set);
sigaddset(&new_set, SIGINT);  // 添加 SIGINT
sigaddset(&new_set, SIGTERM); // 添加 SIGTERM// 阻塞 SIGINT 和 SIGTERM
sigprocmask(SIG_BLOCK, &new_set, NULL);/* 临界区代码(不会被 SIGINT/SIGTERM 中断) */
场景2:解除信号阻塞(SIG_UNBLOCK)
sigset_t unblock_set;
sigemptyset(&unblock_set);
sigaddset(&unblock_set, SIGINT);// 解除 SIGINT 阻塞
sigprocmask(SIG_UNBLOCK, &unblock_set, NULL);
场景3:完全替换屏蔽字(SIG_SETMASK)
sigset_t full_set, old_set;
sigfillset(&full_set);  // 包含所有信号// 阻塞所有信号,保存旧屏蔽字
sigprocmask(SIG_SETMASK, &full_set, &old_set);/* 绝对安全临界区 */// 恢复原始屏蔽字
sigprocmask(SIG_SETMASK, &old_set, NULL);
场景4:获取当前屏蔽字(set=NULL)
sigset_t current_mask;// 获取但不修改当前屏蔽字
sigprocmask(SIG_BLOCK, NULL, &current_mask);// 检查 SIGINT 是否被阻塞
if (sigismember(&current_mask, SIGINT)) {printf("SIGINT is currently blocked\n");
}

特殊信号处理规则

  1. 不可阻塞信号

    // 尝试阻塞 SIGKILL/SIGSTOP 会被忽略
    sigset_t mask;
    sigaddset(&mask, SIGKILL);
    sigprocmask(SIG_BLOCK, &mask, NULL); // 实际无效
    
  2. 信号处理期间的自动屏蔽

    void handler(int sig) {// 执行期间自动阻塞当前信号 (SIGINT)// 同时阻塞 sa_mask 中指定的信号
    }int main() {struct sigaction sa;sa.sa_handler = handler;sigemptyset(&sa.sa_mask);sigaddset(&sa.sa_mask, SIGQUIT); // 额外屏蔽 SIGQUITsigaction(SIGINT, &sa, NULL);
    }
    

多线程注意事项

// 错误!进程级函数影响所有线程
sigprocmask(SIG_BLOCK, &set, NULL); // 正确:线程安全版本
pthread_sigmask(SIG_BLOCK, &set, NULL);
特性sigprocmaskpthread_sigmask
作用范围整个进程单个线程
线程安全
标准POSIX 进程标准POSIX 线程标准
推荐场景单线程程序/主线程初始化多线程程序的信号控制

原子操作保障

危险的非原子操作:
// 第1步:解除阻塞
sigprocmask(SIG_UNBLOCK, &set, NULL);// 此处可能发生信号递送并丢失!// 第2步:等待信号
pause(); // 可能永远阻塞
安全的原子方案:
// 准备等待的信号集
sigset_t wait_mask;
sigemptyset(&wait_mask);
sigaddset(&wait_mask, SIGINT);// 原子操作:设置临时屏蔽+等待
sigsuspend(&wait_mask); // 安全等待SIGINT

完整示例:临界区保护

#include <signal.h>
#include <stdio.h>
#include <unistd.h>void critical_section() {sigset_t new_mask, old_mask;// 步骤1:准备阻塞所有信号sigfillset(&new_mask);// 步骤2:设置屏蔽字(进入临界区)if (sigprocmask(SIG_SETMASK, &new_mask, &old_mask) == -1) {perror("sigprocmask failed");return;}/* ===== 临界区开始 ===== */printf("Entered critical section\n");// 模拟关键操作for (int i = 0; i < 3; i++) {write(STDOUT_FILENO, ".", 1);sleep(1);}write(STDOUT_FILENO, "\n", 1);/* ===== 临界区结束 ===== */// 步骤3:恢复原始屏蔽字if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) {perror("sigprocmask restore failed");}
}int main() {// 设置SIGINT处理signal(SIGINT, SIG_IGN); // 简单忽略printf("Try Ctrl+C during critical section:\n");critical_section();printf("Now Ctrl+C will work:\n");pause(); // 等待信号return 0;
}

运行效果

Try Ctrl+C during critical section:
Entered critical section
...(此时按Ctrl+C无效)
...
Now Ctrl+C will work:
^C  # 程序退出

最佳实践总结

  1. 初始化信号集

    sigset_t set;
    sigemptyset(&set); // 或 sigfillset(&set)
    
  2. 错误检查

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {perror("sigprocmask error");// 错误处理
    }
    
  3. 资源清理

    sigset_t orig_mask;
    sigprocmask(SIG_SETMASK, &new_mask, &orig_mask);
    /* 操作 */
    sigprocmask(SIG_SETMASK, &orig_mask, NULL); // 恢复
    
  4. 配合 sigsuspend

    sigset_t wait_mask;
    // 配置 wait_mask...
    sigsuspend(&wait_mask); // 原子等待
    
  5. 线程环境

    // 使用 pthread_sigmask
    pthread_sigmask(SIG_BLOCK, &set, NULL);
    

sigprocmask 是信号控制的核心枢纽,理解其参数机制和与其它信号函数的协作关系,是编写健壮 Linux 系统程序的关键基础。

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

相关文章:

  • 阿里巴巴1688怎么做网站自建网站阿里云备案通过后怎么做
  • 成都规划网站佛山网上办事大厅官网
  • AI-RAN Sionna 5G NR 开发者套件
  • 百度商桥怎么添加到网站山东网站
  • iis 里没有网站柯桥网站建设
  • 外汇返佣网站建设有了域名之后怎么做自己的网站
  • 模板网站配置文件域名注册 网站建设 好做吗
  • 网站开发工具安卓版泉州网站建设方案服务
  • 长沙网站建设长沙网站制作淘宝优惠券网站建设总代
  • 河北云网站建设福建联泰建设集团网站
  • 基于单片机的蓝牙可调PWM波形发生器设计
  • 网站如何生成静态页面英国网站建设
  • 网站建设人员分工wordpress菜单导航代码
  • 怎么查网站外链企业小程序注册
  • OpenCV(一):创建显示窗口
  • 国际设计网站有哪些吉林省吉林市天气预报
  • 全响应网站制作北京中燕建设公司网站
  • TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 张量(Tensor)的定义与操作
  • 网站授权合同网站服务器查询
  • 网站建设性能分析淘宝网站店铺请人做
  • 泰州网站专业制作如何免费申请域名和网址
  • C61-结构体数组
  • XPath 节点
  • 乐清公司做网站服务外包公司是干什么的
  • MySQL————数据库基础
  • 个人账号密码网站建设怎么制作网站视频
  • 【全志V821_FoxPi】6-2 IMX219 MIPI摄像头适配
  • Python Keras深度学习
  • dede门户网站模版平台推广活动策划方案
  • 什么是文件上传漏洞? 产生该漏洞的原因是什么 ? 它的危害有哪些?