C语言错误处理之 “信号处理方式<signal.h>及signal函数等内置函数”

目录

前言

signal.h头文件

信号宏

signal函数

 实例:在Linux环境下验证signal函数

实例:在Linux中演示保存signal函数的返回值

预定义的信号处理函数(简单了解)

SIG_DFL函数

SIG_IGN函数

raise函数

实例:测试信号


前言

本篇只是依据C标准中的描述来介绍信号,所谈内容有限,但实际信号在UNIX中的作用会更大...

signal.h头文件

作用:提供处理异常情况(信号)的工具:signal函数raise函数

关于"信号“:

1、信号有两种类型:运行时错误(例如除以零)发生在程序以外的事件(例如用户选择中断或终止正在运行的程序)

2、当有错误或外部事件发生时,我们称产生了一个信号

3、大多数信号是异步的,可以在程序执行过程中的任意时刻发生,这也是为什么我们必须用一种独特的方式来处理它们

信号宏

概念:<signal.h>定义了一系列的宏用于表示不同信号,每个宏的值都是一个正整数常量

信号表:

宏名含义
SIGABRT异常终止(可能由于调用abort导致)
SIGFPE在算术运算中发生错误(可能是除以零或溢出)
SIGILL无效指令
SIGINT中断
SIGSEGV无效存储访问
SIGTERM终止请求

注意事项: 对于某个特定的计算机或操作系统,不是所有信号都有意义,大多数C语言的实现都至少支持其中一部分

signal函数

函数原型:signal  (int sig,  void (*func)(int) );

参数解释:第一个参数是特定信号编码sig,第二个参数是一个指向会在信号发生时处理该信号的函数的指针(函数指针)

//signal(信号,处理信号的回调函数)
signal (SIGINT,handler);
//一旦在程序执行过程中出现了SIGINT信号,handler函数就会自动被调用

返回值:返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

作用:回调一个信号处理函数,以便将来设定的信号被触发时使用

注意事项:

1、每个信号处理函数都必须有一个int类型的参数,且返回类型为void,知道是那种信号导致了处理函数被调用是十分重要的,这是因为signal函数允许我们对多个信号使用同一个处理函数

2、信号处理函数可以实现的功能包括:忽略该信号、执行一些错误恢复或终止程序等

3、一旦信号处理函数返回,程序就会从信号发生点恢复并继续执行,但有两种例外情况:

  1. 信号为SIGABRT,处理函数返回时程序异常终止
  2. 信号为SIGFPE,处理函数返回结果未定义

4、signal函数的返回值经常被丢弃,如果需要可以将它保存在变量中:

//定义一个函数指针变量orig_handler
void (*orig_handler)(int);   ...//令该函数指针变量保存指向原来处理函数的地址
orig_handler = signal(SIGINT,handler);//如果想要恢复原来的处理函数,可以使用以下代码:
signal(SIGNINT,orig_handler)

5、信号处理函数即可以自定义,又可以使用<signal.h>提供的两个处理函数 

 实例:在Linux环境下验证signal函数

#include <stdio.h>
#include <signal.h>
typedef void (*signal_handler)(int);void signal_handler_fun(int signum) {printf("catch signal %d\n", signum);
}int main(int argc, char *argv[]) {signal(SIGINT, signal_handler_fun);while(1);return 0;
}

SIGINT表示中断信号,在执行该程序时,我们利用Linux中的CTRL + C键主动退出该程序,每一次的尝试都会导致信号处理函数的执行,这也体现了我们可以自定义信号处理函数

实例:在Linux中演示保存signal函数的返回值

#include <stdio.h>
#include <signal.h>static void SignalHandler1(int signo)
{printf("\nhaha\n");
}
static void SignalHandler2(int signo)
{printf("\nhehe\n");
}
int main()
{void (*func)(int);if ((func = signal(SIGINT, SignalHandler1)) == SIG_ERR){perror("signal\n");}sleep(10);if ((func = signal(SIGINT, SignalHandler2)) == SIG_ERR){perror("signal");}sleep(10);func(2);return 0;
}

^C//第一次触发signal
haha//信号处理函数是SignalHandler1,此时signal的返回值是以前的处理signo的函数指针,是系统默认的
^C//第二次触发signal
hehe//信号处理程序是SignalHandler2,此时signal的返回值是以前的处理signo的函数指针,应该是SignalHandler1haha//所以此处输出的是SignalHandler1的结果

预定义的信号处理函数(简单了解)

除了自己编写信号处理函数,还可以选择使用<signal.h>提供的预定义的信号处理函数,这样的函数一共有两个,它们都是用宏来表示的:

SIG_DFL函数

概念:SIG_DFL函数按默认的方式处理信号

作用:程序终止

SIG_IGN函数

概念:SIG_IGN函数按忽略的方式处理信号

作用:程序继续运行

raise函数

函数原型:int raise (int sig);

作用:触发信号(从被动接收信号改为设置监测点主动触发信号)

raise (SIGABRT);

返回值:raise函数的返回值可以用来测试调用是否成功:0表示成功,非0表示失败

实例:raise函数的使用

#include <stdio.h> //需导入此头文件
#include <signal.h>int main() {printf("请输入一个正整数,单数直接杀死进程,双数正常退出\n");int num;scanf("%d", &num); // 从标准输入读取数据if (num % 2 == 1) {raise(SIGKILL);}printf("正常退出\n");return 0;
}

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员必备注释模板---佛祖保佑

佛祖保佑【一】 /*** _ooOoo_* o8888888o* 88" . "88* (| -_- |)* O\ /O* ____/---\____…

leetcode 255.用队列实现栈

255.用队列实现栈 不出意外大概率这几天都会更新 leetcode&#xff0c;如果没有做新的题&#xff0c;大概就会把 leetcode 之前写过的题整理&#xff08;单链表的题目居多一点&#xff09;出来写成博客 今天讲的题蛮容易出错的&#xff08;注意传参啊&#xff0c;最好把队列的…

渗透测试——五、网站漏洞——SQL注入

一、走进DVWA测试网站 1、网站渗透测试步骤 (1)收集信息 1、获取域名的 Whois 信息&#xff0c;获取注册者邮箱、姓名、电话等。2、查询服务器旁站及子域名站点&#xff0c;因为主站一般比较难&#xff0c;所以先看看旁站有没有通用性的CMS或者其他漏洞。3、查看服务器操作系…

解决 nginx 504 Gateway Time-out报错问题

国内GPT4站点&#xff1a;海鲸AI 要延长 Nginx 服务器在返回 504 Gateway Time-out 错误之前等待上游服务器响应的时间&#xff0c;你需要修改 Nginx 配置文件中的超时设置。以下是一些可能需要调整的指令&#xff1a; proxy_connect_timeout&#xff1a;代理服务器与上游服务…

ROS话题通信基本操作(C++)

目录 一、发布 1、实现步骤 2、代码实例 二、接收 1、实现步骤 2、代码实例 三、配置运行 1、修改CMakeLists.txt 2、运行结果 一、发布 1、实现步骤 1.包含头文件 2.初始化 ROS 节点:命名(唯一) 3.实例化 ROS 句柄 4.实例化 发布者 对象 5.组织被发布的数据&#…

Pytest做性能测试?

Pytest其实也是可以做性能测试或者基准测试的。是非常方便的。 可以考虑使用Pytest-benchmark类库进行。 安装pytest-benchmark 首先&#xff0c;确保已经安装了pytest和pytest-benchmark插件。可以使用以下命令安装插件&#xff1a; pip install pytest pytest-benchmark …

JSP控制项目启动后默认去访问指定的WebServlet 而不是index.jsp

我的 index.jsp 代码是这样 现在每次启动 访问的都是index.jsp 这也是它的默认配置 我这里写了一个 WebServlet 代码是这样 简单可以理解为 我们定义了WebServlet 访问路径为1cginServlet 其中在request作用域中 定义了一个userName值为 欢迎来到jsp世界 然后 跳转向 page.j…

十年婚姻·总结三

十年婚姻总结三 婚姻这个制度&#xff0c;就不是为了保护爱情和情感的&#xff0c;是为了保护财产和育儿 婚姻这个制度&#xff0c;就不是为了保护爱情和情感的&#xff0c;是为了保护财产和育儿 问题&#xff1a;为什么男人喜欢外面的女人&#xff0c;也不离婚&#xff1f; …

Rust编程语言入门教程(三)-trait

文章目录 Rust编程语言入门教程&#xff08;三&#xff09;-trait什么是 trait&#xff1f;trait使用举例 Rust编程语言入门教程&#xff08;三&#xff09;-trait 什么是 trait&#xff1f; trait 是 Rust 中的接口&#xff0c;它定义了类型使用这个接口的行为。你可以类比到…

Android : AndroidStudio开发工具优化

1.开启 gradle 单独的守护进程 Windows: 进入目录 C:\Users\Administrator\.gradle 创建文件&#xff1a; gradle.properties # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Settings specified in this file will override any Gradle s…

前端时间的失败总结复盘

分享失败经验&#xff0c;前段时间的总结复盘&#xff1a; 与伙伴合作面对异常决策要及时提出质疑&#xff0c;怼&#xff0c;别太客气&#xff0c;客气起来&#xff0c;小心翼翼在意他人情绪那么这个项目就会让人难受&#xff0c;不要因为因为伙伴身上有标签/光环/权威就觉得…

怎么把视频转换为gif?

怎么把视频转换为gif&#xff1f;视频和 GIF 动图在许多方面都有所不同&#xff0c;主要的区别包括它们的数据格式、播放方式以及用途。视频&#xff1a;通常以常见的视频格式如MP4、AVI、MOV等存储&#xff0c;它们包含了连续的图像帧以及音频轨道&#xff08;如果有的话&…

ISP算法简述-BLC

Black Level Calibration, 黑电平矫正 现象 1)在纯黑条件下拍张图&#xff0c;你会发现像素值不为0 2)或者你发现图像整体偏色 这些问题可能是黑电平导致的。 原因 存在黑电平的原因有2个&#xff1a; 1)sensor的电路本身存在暗电流。暗电流主要产生在光电信号转换过程中&#…

国内某求职app遭“撞库”攻击,百万条用户数据泄露

什么是撞库&#xff1f; 简单来说&#xff1a;一些用户为了方便记忆&#xff0c;会采用相同的账户密码登录多个网站或app&#xff0c;甚至是存储关键信息的系统平台。如果其中一个平台有漏洞被黑客利用窃取了账户名和密码&#xff0c;黑客便用这套凭证登录大量测试所有平台&am…

葡萄酒的储存条件会影响葡萄酒的陈酿吗?

自20世纪末以来&#xff0c;葡萄酒储存有关的行业一直在增长&#xff0c;一些葡萄酒鉴赏家可能会选择将葡萄酒存放在家里的专用房间或壁橱里。 自云仓酒庄品牌雷盛红酒分享总所周知&#xff0c;瓶装葡萄酒的储存条件是会影响葡萄酒的陈酿&#xff0c;振动和热波动会加速葡萄酒的…

COCO格式标签(json)内容可视化(python)

主要是查到的可用代码&#xff0c;便于自己使用查询&#xff0c;和有相关需求的提供参考。 代码是MMYOLO下的可视化代码browse_coco_json.py&#xff0c;有json文件和图像文件&#xff0c;可以直接输入执行&#xff0c;输出会把bbox、mask等类型标注展示。 下面直接上代码&am…

【深度学习笔记】09 权重衰减

09 权重衰减 范数和权重衰减利用高维线性回归实现权重衰减初始化模型参数定义 L 2 L_2 L2​范数惩罚定义训练代码实现忽略正则化直接训练使用权重衰减 权重衰减的简洁实现 范数和权重衰减 在训练参数化机器学习模型时&#xff0c;权重衰减&#xff08;decay weight&#xff09…

python中获取函数签名(参数)

说明 有些时候我们不清楚python的函数的具体签名的时候&#xff0c;调用可能会报错&#xff0c;这里就是介绍一种简单的方法来获取函数的签名参数。 语法 获取函数的参数签名可以使用 组件.函数.__signature__示例&#xff1a; 我想要获取streamlit.text_input函数的参数签…

golang开发之个微机器人开发

请求URL&#xff1a; http://域名地址/sendFile 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是string登录实例标识wcId是string接收…

使用Redis实现购物车后端处理

本文中心思想&#xff1a;实现购物车的后端处理逻辑。 本文将教会你掌握&#xff1a;1&#xff0e;存储商品信息&#xff0c;2&#xff0e;存储购物车信息&#xff0c;3&#xff0e;获取购物车信息。 存储商品信息 商品包含多个属性&#xff0c;例如&#xff1a;名字&#x…