11信号学习之sigaction函数及使用其实现信号捕捉案例(信号最重要的一节)

2023-10-26

概述:
注意:在我关于信号的文章中,我所说的系统的mask的意思实际上是进程的mask,每个进程的mask都是唯一的,所以我就将其称为系统的,但不能理解为每个进程的mask都是共用的。

1 sigaction函数

  • 1)上一篇我们说的signal函数捕捉信号,但是他不是POSIX标准,在不同的操作系统上可能执行不了。所以我们项目开发时需要使用本节接下来所讲的sigaction函数捕捉。
  • 2)并且需要强调下面struct sigaction结构体的成员sigset_t sa_mask,它的作用域是只在回调函数生效(并且只针对本信号),其余地方不生效,即其余时间系统的mask生效。而sigprocmask函数的参2const sigset_t *set也是屏蔽字,但是它代表的意思是程序的整个生存期,它的意思和我前面讲信号的过程那张图一样。这点需要区别。这一点不懂的可以看第4点。
  • 3)将sa_mask设成只在回调函数生效的原因是因为:例如2号信号产生,进入2号的回调函数处理,处理到一半时,结果2号信号又被触发,那么程序又被重新执行,这样的结果相对于递归了,是不合理的。所以这样设计之后,当我在回调函数处理自己的逻辑时,即使再来同样的信号,由于此时只在回调函数生效,不在sigaction生效,sigaction使用的是系统的mask屏蔽字,它会去执行默认的处理方式,而不再执行回调函数。这一点不是特别难懂,用心看一下即可。
  • 4)再次总结sa_mask只在回调生效,其余不生效,并且在回调函数中系统的mask也是有效的。或者我们这样更好理解,执行回调函数的sa_mask屏蔽字只对本信号有效,其余信号不起效,仍然会使用系统的mask。例如注册了2信号,按下ctrl+c后触发,在其执行期间再次按下ctrl+c不起效,但是按下ctrl+\这些信号是有效的(但是你可以提前设置sa_mask屏蔽其它信号),仍然可以终止程序,因为系统的mask屏蔽字还存在,所以sa_mask是针对于本信号的屏蔽字,和其它信号屏蔽字无关。这点是没有错的。

关于sa_mask与系统的mask的特性可以看我下一篇信号捕捉的特性解释。

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 
/*
	 功能:通常在Linux(其它系统也差不多)用其来注册一个信号的捕捉函数,然后修改其处理动作。
	 成功:0;失败:-1,设置errno。
	 参1:信号值编号。
	 参2:传入参数,新的处理方式。
	 参3:传出参数,旧的处理方式。	

	struct sigaction {
        void     (*sa_handler)(int);
        void     (*sa_sigaction)(int, siginfo_t *, void *);//当sa_flags被指定为SA_SIGINFO标志时,使用该信号处理程序。(很少使用)
        sigset_t   sa_mask; 
        int       sa_flags; 
        void     (*sa_restorer)(void);该成员是过时的,不应该使用,POSIX.1标准将不指定该元素。(弃用)
    };

	重点掌握上面结构体的成员:
	① sa_handler:指定信号捕捉后的回调处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略 或 SIG_DFL表执行默认动作。
	② sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字),通常传0的屏蔽集。注意:仅在回调处理函数被调用期间屏蔽生效,是临时性设置。在主函数或者非回调函数该屏蔽字是不生效的,生效的是系统的mask屏蔽字。
	③ sa_flags:通常设置为0,表使用默认属性。	
*/

2 sigaction函数案例

案例1,使用sigaction函数捕捉一个信号。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

/*自定义的信号捕捉函数*/
void sig_int(int signo)
{
	printf("catch signal SIGINT\n");//单次打印
    sleep(10);
    printf("----slept 10 s\n");
}

int main(void)
{
	struct sigaction act;		

	act.sa_handler = sig_int;
	sigemptyset(&act.sa_mask);		//传0屏蔽集,不屏蔽任何信号,sa_mask只在sig_int函数有效
	act.sa_flags = 0;				//默认属性

	int ret = sigaction(SIGINT, &act, NULL);
	if(ret == -1){
		printf("sigaction failed.\n");
		return -1;
	}

    printf("------------main slept 10\n");
    sleep(10);

	while(1);//该循环只是为了保证有足够的时间来测试函数特性

	return 0;
}

案例2,使用sigaction函数捕捉多个信号。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

/*自定义的信号捕捉函数*/
void sig_int(int signo)
{
	if(signo == SIGINT){
		printf("catch signal SIGINT\n");
	}else if(signo == SIGQUIT){
		printf("catch signal SIGQUIT\n");
	}
	
	return;
}

int main(void)
{
	struct sigaction act;		

	act.sa_handler = sig_int;
	sigemptyset(&act.sa_mask);		//传0屏蔽集,不屏蔽任何信号,sa_mask只在sig_int函数有效
	//sigprocmask(SIGINT, act, NULL);//注意调用该函数是将信号集添加到系统的信号集,所以要想只在回调生效则不应该调用这一步
	act.sa_flags = 0;				//默认属性

	int ret = sigaction(SIGINT, &act, NULL);
	if(ret == -1){
		printf("sigaction failed.\n");
		return -1;
	}
	ret = sigaction(SIGQUIT, &act, NULL);//即ctrl+\
	if(ret == -1){
		printf("sigaction failed.\n");
		return -1;
	}

    printf("------------main slept 10\n");
    sleep(10);

	while(1);//该循环只是为了保证有足够的时间来测试函数特性

	return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

11信号学习之sigaction函数及使用其实现信号捕捉案例(信号最重要的一节) 的相关文章

  • 我应该使用哪个 Linux 发行版作为 Xen 主机? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我为家庭办公室订购了一台服务器 我想用 Xen 对其进行分区 我认为这将使事情保持干净并且更容易维护 我将运行 MySQL PostgreSQL
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 如何确保 numpy BLAS 库可用作动态加载库?

    The theano安装文档 http www deeplearning net software theano install html troubleshooting make sure you have a blas library指
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • 如何查明 Ubuntu 上安装了哪个版本的 GTK+?

    我需要确定 Ubuntu 上安装了哪个版本的 GTK 男人似乎不帮忙 这个建议 https stackoverflow com a 126145 会告诉您安装了哪个 2 0 的次要版本 不同的主要版本将具有不同的包名称 因为它们可以在系统上
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • 如何在特定 systemd 服务重新启动时触发自定义脚本运行

    我想知道如何安排自定义脚本在重新启动服务时运行 我的用例是 每当重新启动 Tomcat 服务时 我都必须运行多个命令 我想知道是否有一种方法可以编写脚本并安排它在重新启动 Tomcat 服务时运行 我已将 tomcat 脚本设置为 syst
  • Composer 安装要求

    我正在尝试将 Composer 安装到 Laravel 项目中 当我做的时候sudo composer install在项目目录中它显示了两个错误 Problem 1 Installation request for simplesoftw
  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • PHP 致命错误:未找到“MongoClient”类

    我有一个使用 Apache 的网站 代码如下 当我尝试访问它时 我在 error log 中收到错误 PHP Fatal Error Class MongoClient not found 以下是可能错误的设置 但我认为没有错误 php i
  • 如何制作和应用SVN补丁?

    我想制作一个SVN类型的补丁文件httpd conf这样我就可以轻松地将其应用到其他主机上 If I do cd root diff Naur etc httpd conf httpd conf original etc httpd con
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复

随机推荐

  • stm32+hx711+蓝牙hc05 称重系统(蓝牙电子秤)

    stm32 称重模块hx711 蓝牙模块hc05 本项目使用主控stm32f103c8t6 称重模块hx711 蓝牙模块hc05上传至手机app 电脑app显示数值 模块 1 stm32f103c8t6最小系统板 2 hx711 HX711
  • DataStore入门及在项目中的使用

    首先给个官网的的地址 应用架构 数据层 DataStore Android 开发者 Android Developers 小伙伴们可以直接看官网的资料 本篇文章是对官网的部分细节进行补充 一 为什么要使用DataStore 代替Shared
  • 起飞!8个 Python 加速运行骚操作

    转自 网络 本次分享纯Python编程的加速运行方法 Python 是一种脚本语言 相比 C C 这样的编译语言 在效率和性能方面存在一些不足 但是 有很多时候 Python 的效率并没有想象中的那么夸张 本文对一些 Python 代码加速
  • 2020年09月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

    C C 编程 1 8级 全部真题 点这里 第1题 铺砖 对于一个2行N列的走道 现在用12 22的砖去铺满 问有多少种不同的方式 时间限制 3000 内存限制 131072 输入 整个测试有多组数据 请做到文件底结束 每行给出一个数字N 0
  • 常见三方结算周期都是有哪些?

    T1 为工作日次日 就是一个工作日结算 如遇到节假日 则延迟到节假日结束后第一个工作日结算 T0 为工作日当天结算 当然如遇节假日 节假日中的交易不结算 延迟到节假日结束后的第一个工作日统一结算 D1 为交易后自然日次日结算 包含节假日内
  • Streamlit 讲解专栏(三):两种方案构建多页面

    文章目录 1 前言 2 第一种方案 使用Session State实现多页面交互 2 1 Session State简介 2 2 多页面应用的基本结构 2 3 实现多页面交互的代码示例 2 4 Session State机制的优缺点 3 第
  • 如何实现 Array 和 List 之间的转换?

    在 Java 中 我们可以通过以下方法实现 Array 和 List 之间的转换 数组转 List String arr apple banana orange List
  • 2023最新宝塔面板8.0.1企业版开心版

    宝塔面板是目前一个非常好用的可视化面板 这几天我自己搭建了一个宝塔云端 不经过宝塔官方接口 无需绑定手机号 安装之后直接显示企业版 所有插件全部免费使用 付费的也能使用 脚本如下 centos安装脚本 yum install y wget
  • 【蓝牙开发】Andorid蓝牙绝对音量

    蓝牙绝对音量相关基础知识 1 什么是绝对音量 Android 蓝牙部分的官方文档有如下描述 Androud Bluetooth Service 在 Android 6 0 及更高版本中 Android 蓝牙堆栈允许音频源设置绝对音量 以便用
  • 【毕业设计】深度学习行人重识别算法研究与实现 - python opencv yolo Reid

    文章目录 0 前言 1 课题背景 2 效果展示 3 行人检测 4 行人重识别 5 其他工具 6 最后 0 前言 Hi 大家好 这里是丹成学长的毕设系列文章 对毕设有任何疑问都可以问学长哦 这两年开始 各个学校对毕设的要求越来越高 难度也越来
  • WIN10的传递优化文件是个什么鬼?能删除吗?

    Win10正式版系统使用时间长了以后 电脑磁盘总会产生一些冗余的文件和磁盘碎片 我们可以用一些工具软件对硬盘进行优化和处理 其实利用系统自带的工具也可以清理磁盘的 但在操作过程中 我们常常会看到一个名叫 传递优化文件 的选项 而且多数情况下
  • UA到底是什么

    欢迎关注勤于奋 每天12点准时更新国外LEAD相关技术 今天这篇文章也是比较基础的文章 其实有很多新手还是搞不懂 所以我特意来写篇文章聊聊这个UA 到底是什么 在我们国外LEAD当中起到的作用 如果搞不懂 很多东西你都没有办法灵活运用 首先
  • 19款资源整合类网站推荐:每一个网站都堪称以一敌百

    强烈推荐这19个资源聚合网站 每一个网站都足以堪称 以一敌百 因为每一个网站都聚合了相当多不同类型 不同领域的网站资源 并且做了分类导航方便大家查找使用 所以 与其收藏那么多零碎的网址 不如收藏下面这些网站资源 比格张 发现更好的资源 一个
  • java8的日期工具类(获取当前时间 相隔天数 小时 分钟 秒等处理)

    package com example list test import java text ParseException import java text SimpleDateFormat import java time import
  • tvm 入门(二)

    代码是一个tvm入门的例子 以向量相加为例 使用tvm的流程是 1 描述串行的向量相加是怎么做的 2 描述并行的时候 怎么对计算单元做划分 3 编译目标函数 本文所示代码可以看到用tvm生成的cuda代码 4 把编译生成的内容保存成文件 加
  • VMware Workstation 未能启动 VMware Authorization Service。您可以尝试手动启动 VMware Authorization Service。如果此问题仍然存

    报错界面 解决方法一 管理员身份运行即可 解决方法二 打开服务 找到VMware Authorization Service右键选择然后点启动 然后发现又报了下面的错误 不慌这时候打开属性把启动类型改成手动即可
  • String、StringBuffer和StringBuilder的异同点

    String StringBuffer StringBuilder三者的异同 String 不可变的字符序列 底层使用char 存储 StringBuffer 可变的字符序列 线程安全的 效率低 底层使用char 存储 StringBuil
  • OpenAI的人工智能语音识别模型Whisper详解及使用

    1 whisper介绍 拥有ChatGPT语言模型的OpenAI公司 开源了 Whisper 自动语音识别系统 OpenAI 强调 Whisper 的语音识别能力已达到人类水准 Whisper是一个通用的语音识别模型 它使用了大量的多语言和
  • 安装mingw出现download failed和unable to continue

    利用mingw get setup安装mingw总是出现download failed和unable to continue错误 截图如下 错误原因 因为服务器在外网 可能是对方服务器不稳定 连接出错等问题导致 解决办法 下载对应等离线安装
  • 11信号学习之sigaction函数及使用其实现信号捕捉案例(信号最重要的一节)

    概述 注意 在我关于信号的文章中 我所说的系统的mask的意思实际上是进程的mask 每个进程的mask都是唯一的 所以我就将其称为系统的 但不能理解为每个进程的mask都是共用的 1 sigaction函数 1 上一篇我们说的signal