目录
一、什么是信号
kill-l查看信号
二、信号的产生
2.1系统调用
kill
raise
abort
2.2软件条件
13)SIGPIPE pipe信号
14)SIGAKARM alarm信号
2.2硬件中断
2.3异常
8)SIGFPE 除0异常
11)SIGSEGV 野指针
2.4信号处理的常见方式
三、Core Dump和term
core
term
一、什么是信号
kill-l查看信号
二、信号的产生
2.1系统调用
系统调用作为C/C++学习过程中是必不可少的一个内容,因为安全性和操作系统的规则,用户想要执行某些系统层面的操作时,必须通过系统调用来让操作系统执行,而之前提到的kill指令就是通过系统调用来实现的。
kill
通过kill可以向任意的进程发送任意的信号。
raise
自己给运行自己的进程发送信号。
abort
终止自己,向自己发送6号信号。
2.2软件条件
13)SIGPIPE pipe信号
在博主之前的文章中曾详细介绍过pipe的使用,管道是一个文件,本质是软件,管道写端退出了,读端一直在读,操作系统就会认为条件不满足,就会发13号信号让该进程退出。
14)SIGAKARM alarm信号
设置一个闹钟,到了时间执行对应指令,默认动作时term终止进程。
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动
作是终止当前进程。
alarm(0) 取消闹钟
闹钟函数是一个系统调用,设定闹钟,本质是在OS内部设定的,操作系统要定期将用户级的数据从缓冲区刷新到外设,此时就要求操作系统具有定时功能, 所以操作系统内部存在很多闹钟,所以就需要先描述再组织,此时就有一个alarm结构体,而判断闹钟是否到了时间只需要将闹钟设置的时间和现在的时间进行比较,如果时间到了就触发,所以我们可以建立一个最小堆,每次只需要判断堆顶的数据是否超时就可以。
2.2硬件中断
2.3异常
8)SIGFPE 除0异常
11)SIGSEGV 野指针
2.4信号处理的常见方式
三、Core Dump和term
在Linux信号中,绝大部分信号都会执行core或term,其效果都是终止进程,那么二者之间有什么区别呢。
core
比如代码发生除0错误时就会引发core,此时编译器会报错,但在当前目录下依旧会形成可执行文件,此时执行可执行文件就会出现Float Point exception 也就是除0错误。
ulimit-a查看core是否被打开
ulimit-c num打开core dump功能,num按需求去取,单位是block,此时当前目录下就会形成一个core文件。
再次运行除零错误的代码依旧会报错,Float Point exception (core dumped)。
所以为什么要有core文件呢?OS可以通过core文件定位到进程为什么退出,以及执行到哪一行退出的。
core文件是什么呢?将进程在内存中的核心数据(与调试有关)转储到磁盘中形成core/core.pid的文件。
而core文件的功能就是协助我们进行调试。
以下运行一个代码,假设代码中包含除0错误,生成可执行后,gdb可执行程序,输入 core-file指令就会显示出代码出问题的行数。
这种方式也叫事后调试。
而云服务器一般都是默认关闭核心转储功能,也就是默认将进程core退出,进行了特定的设定,默认core是被关闭的。
在线上服务中,最重要的就是让服务功能持续的跑起来,而一旦代码出现问题,如果此时core是开启的就会在当前路径下形成一个core文件,core文件也是很大的,如果问题没有得到及时的解决,可能os就会一直形成core文件,从而不断的占用磁盘空间。主要是防止未知的core dump一直在进行。
而在unbuntu中即使打开了core也不会像centos下在core文件后缀pid,这样即使一直生成core文件也只会在当前目录下反复覆盖生成一个core,就很好的规避了上述问题。
而在进程控制中的这个core dump标志就表示是否发生了核心转储,为0表示没有发生,1表示发生了。
term
term就是正常的直接退出