信号就是软中断。
信号提供了异步处理事件的一种方式。例如,用户在终端按下结束进程键,使一个进程提前终止。
1、信号概念
每一个信号都有一个名字,它们的名字都以SIG打头。例如,每当进程调用了abort函数时,都会产生一个SIGABRT信号。
每一个信号对应一个正整数,定义在头文件
2、信号产生的场景
- 当用户在终端按下特定的键时,会产生信号。例如,当用户按下DELETE按键(或Control-C)时,会产生一个中断信号(interrupt signal,SIGINIT),该信号使得一个运行中的程序终止。
- 硬件异常可以产生信号。会引发硬件异常的情况如除以0,非法内存引用(invalid memory reference)等。这种情况会被硬件检测到,并通知内核,然后内核产生相应的信号通知对应的运行进程。例如,当一个进程执行了一个非法的内存引用,会触发SIGSEGV信号。
- kill函数允许当前进程向其他的进程或者进程组发送任意的信号。当然,这种方法存在限制:我们必须是信号接收进程的所有者,或者我们必须是超级用户(superuser)。
- kill命令的作用和kill函数类似。这个命令多用户杀死后台进程。
- 软件异常可以根据不同的条件产生不同的信号。例如:网络连接中接受的数据超出边界时,会触发SIGURG信号。
对于进程来说,信号是随机产生的,所以进程不能简单地根据检测某个变量是否改变来判断信号是否发生,而应该告诉内核“当这个信号发生时,做下面的这些事情”。
3、信号的处理方式
对于进程来说,不能判别是否出现一个信号,而是必须要告诉内核信号出现的时候,执行下列操作。
信号的处理方式有三种:
1. 忽略此信号
2. 执行信号的默认处理动作。
3. 提供自定义行为,要求处理该信号的时候切换到用户态执行这个处理函数,也叫做捕捉一信号。
注:捕捉信号的时候需要注意不能捕捉SIGKILL信号和SIGSTOP信号。当捕捉到SIGCHLD信号,这个时候标识一个子进程已经终止,所以这个时候我们可以调用waitpid函数来取得该子进程的进程ID以及它的终止状态。
对于一些信号发生时,会造成进程终止,同时生成一个core文件,该core文件记录了该进程终止时的内存情况,可以帮助调试和调查进程的终止状态。
有几种情况不会生成core文件:
* 如果进程设置了suid位(chmod u+s file),并且当前用户不是程序文件的所有者;
* 如果进程设置了guid位(set-group-ID),并且当前用户不是程序文件的组所有者;
* 如果过户没有当前工作目录的写权限;
* 如果core文件已经存在,并且用户没有该文件的写权限;
该core文件太大(由参数RLIMIT_CORE限制)
4、产生信号
(1)终端产生信号
首先提出一个概念叫做 core dump,我想在linux下写c,肯定不少发现错误的时候报这个错误接下来我们先来看看这个东西到底是个什么。
core dump叫做核心转储,也叫做核心文件(core file),是操作系统在进程收到某些信号而终止运行时,将此时进程的地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件,这个信息我们常常用于调试程序。
默认的linux系统当中是不生成这个文件的,我们可以使用 ulimit -a 查看系统中这个文件的大小。
我们可以使用命令 ulimit -c xxxx 设置生成的core dump的大小。
默认情况下,生成的core dump文件的格式是core.xxx,后面一般都是pid。并且生成在当前目录下。
现在我们模拟生成一下这样的core dump文件,我们首先写出一个死循环。
int main()
{
printf("hello world\n");
while(1);
return 0;
}
我们运行这个程序,然后操作,Ctrl+\,这样就会出现: