linux signal信号学习

本文详细介绍了Linux系统中的信号机制,包括信号的产生、处理方式和默认行为。重点讨论了使用signal函数进行信号捕捉,解释了signal函数的工作原理和示例代码,展示了如何注册信号处理函数。同时列举了常见的Linux标准信号及其用途。
摘要由CSDN通过智能技术生成

参考资料

linux下20种信号实例说明
http://blog.chinaunix.net/uid/28852942/year-201305-list-1.html

sigaction函数sa_flags各标志影响的实例讲解
http://blog.chinaunix.net/uid-28852942-id-3754478.html

linux系统编程之信号(四):信号的捕捉与sigaction函数
https://blog.csdn.net/jnu_simba/article/details/8947410

sigpipe的解决方法
https://blog.csdn.net/pananing/article/details/18839099

SIGSEGV 信号的捕获与 sigaltstack 系统调用
https://blog.csdn.net/Longyu_wlz/article/details/108720745

1. 信号概述

何为信号:信号就是由用户、系统或进程发送给目标进程的信息,以通知目标进程中某个状态的改变或是异常。
信号产生:总体来说,其产生的条件有两种,分别是:硬件和软件原因,又称为:硬中断和软中断可细分为如下几种原因:
①系统终端Terminal中输入特殊的字符来产生一个信号,比如按下:ctrl+\ 会产生SIGQUIT信号。
②系统异常。比如访问非法内存和浮点数异常。
③系统状态变化。如设置了alarm定时器,当该定时器到期时候会引起SIGVTALRM信号。
④调用了kill命令或是kill函数。

1.1 系统如何处理信号

Linux系统对于接收到的信号(无论是硬中断还是软中断)可以有三种处理方式:
(1)忽略此信号。SIG_IGN,该常数表示信号函数的忽略。在/usr/include/x86_64-linux-gnu/bits/signum.h
头文件中有SIG_IGN的宏定义

#define SIG_IGN	((__sighandler_t) 1) /* 忽略信号  */

(2)执行系统默认的动作。SIG_DFL,该常数表示信号的默认值。对于大多数的系统来说,系统的默认动作就是终止该进程。在/usr/include/x86_64-linux-gnu/bits/signum.h
头文件中有SIG_IGN的宏定义

#define SIG_DFL	((__sighandler_t) 0)  /* 默认动作  */

值得注意的是:Linux下的系统默认动作一般有如下几种:
①结束进程(Term)
②忽略信号(Ignore)
③结束进程并生成核心转储文件(Core),该文件用于gdb后期调试
④暂停进程(Stop)
⑤继续进程(Continue),如果进程被挂起,则恢复进程的运行。否则,忽略该信号。

(3)捕捉该信号。这里需要用户自定义一个函数,来对产生的信号进行捕捉,而在这个函数中可执行用户希望对这个事件进行的处理操作。

2. 使用signal函数捕捉信号

在处理由系统产生的一个信号时候,首先得对产生的该信号进行安装登记,这样才能对其进行处理。何为安装登记呢?其实很好理解,好比你去图书馆借阅图书,当你找到了喜欢的书籍后,再用借书卡去机器上面扫描登记,然后就可以带走该书籍去阅读了。这里的图书相当于信号,用借书卡登记和对信号进行登记同个道理,处理信号相当于你将书籍带离图书馆阅读。Linux上有两个函数都可用来对信号进行登记,分别是:signal和 sigaction
这两个函数的区别:
(1)signal是在系统调用的基础上实现,是库函数,它有两个参数,不支持信号传递信息,主要用于kill -l 中的前32个非实时信号的安装。
(2)sigaction是较新的函数,(由sys_signal和sys_rt_sigaction两个系统调用实现 ),有3个参数。支持信号传递信息,主要用来和sigqueue系统调用配合使用。

2.1 signal详解

 #include <signal.h>

 typedef void (*sighandler_t)(int);

 sighandler_t signal(int signum, sighandler_t handler);

- 函数说明:设置信号处理方式。signal()会依参数signum指定的信号编号(0~64)来设置该信号 的处理函数。当指定的信号到底时,就会跳转到参数handler指定的函数执行。

  • signal函数成功时返回一个函数指针,该函数指针的类似也是sighandler_t。返回值是前一次调用signal函数时传入的函数指针,或者是信号signum对应的默认处理函数指针SIG_DFL(如果是第一次调用的话)
  • signal系统调用出错时返回SIG_ERR并设置errno。
#define SIG_ERR	((__sighandler_t) -1)		/* 错误返回  */

代码1

/*************************************************************************
 * File Name: signal.cpp
 * Author:    The answer
 * Function:  Other        
 * Mail:      2412799512@qq.com 
 * Created Time: 2018年05月13日 星期四 18时47分11秒
 ************************************************************************/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
using namespace std;

void sig_handler(int signum)
{
    if(0 > signum)
    {
        fprintf(stderr,"sig_handler param err. [%d]\n",signum);
        return;
    }
    if(SIGINT == signum)
    {
        printf("Received signal [%s]\n",SIGINT==signum?"SIGINT":"Other");
    }
    if(SIGQUIT == signum)
    {
        printf("Received signal [%s]\n",SIGQUIT==signum?"SIGQUIT":"Other");
    }

    return;
}

int main(int argc,char **argv)
{
    printf("Wait for the signal to arrive.\n ");

    /*登记信息*/
    signal(SIGINT,sig_handler);
    signal(SIGQUIT,sig_handler);

    pause();
    pause();

    signal(SIGINT,SIG_IGN);
    return 0;
}

程序运行后会一直等待用户的输入,当在终端按下ctrl+c时候会打印^C Received signal [SIGINT]
说明捕获到了SIGINT信号,接着程序继续等待,当按下ctrl+\时候会打印^\Received signal [SIGQUIT]
表明捕获到了SIGQUIT信号,如下图所示:

在这里插入图片描述
在Linux的目录/usr/include/x86_64-linux-gnu/bits/signum.h下有对所有信号的宏定义,所以可以用来和int值进行比较。

在这里插入图片描述

3. Linux标准信号

在Linux终端下 kill -l 可以查看所有的信号。
在这里插入图片描述

$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

这里是上面64种信号的说明:

信号起源默认行为含义
SIGHUPPOSIXTerm控制终端挂起
SIGINTANSITerm键盘输入以终端进程(ctrl + C)
SIGQUITPOSIXCore键盘输入使进程退出(Ctrl + \)
SIGILLANSICore非法指令
SIGTRAPPOSIXCore断点陷阱,用于调试
SIGABRTANSICore进程调用abort函数时生成该信号
SIGIOT4.2BSDCore和SIGABRT相同
SIGBUS4.2BSDCore总线错误,错误内存访问
SIGFPEANSICore浮点异常
SIGKILLPOSIXTerm终止一个进程。该信号不可被捕获或被忽略
SIGUSR1POSIXTerm用户自定义信号之一
SIGSEGVANSICore非法内存段使用
SIGUSR2POSIXTerm用户自定义信号二
SIGPIPEPOSIXTerm往读端关闭的管道或socket链接中写数据
SIGALRMPOSIXTerm由alarm或settimer设置的实时闹钟超时引起
SIGTERMANSITerm终止进程。kill命令默认发生的信号就是SIGTERM
SIGSTKFLTLinuxTerm早期的Linux使用该信号来报告数学协处理器栈错误
SIGCLDSystem VIgn和SIGCHLD相同
SIGCHLDPOSIXIgn子进程状态发生变化(退出或暂停)
SIGCONTPOSIXCont启动被暂停的进程(Ctrl+Q)。如果目标进程未处于暂停状态,则信号被忽略
SIGSTOPPOSIXStop暂停进程(Ctrl+S)。该信号不可被捕捉或被忽略
SIGTSTPPOSIXStop挂起进程(Ctrl+Z)
SIGTTINPOSIXStop后台进程试图从终端读取输入
SIGTTOUPOSIXStop后台进程试图往终端输出内容
SIGURG4.3 BSDIgnsocket连接上接收到紧急数据
SIGXCPU4.2 BSDCore进程的CPU使用时间超过其软限制
SIGXFSZ4.2 BSDCore文件尺寸超过其软限制
SIGVTALRM4.2 BSDTerm与SIGALRM类似,不过它只统计本进程用户空间代码的运行时间
SIGPROF4.2 BSDTerm与SIGALRM 类似,它同时统计用户代码和内核的运行时间
SIGWINCH4.3 BSDIgn终端窗口大小发生变化
SIGPOLLSystem VTerm与SIGIO类似
SIGIO4.2 BSDTermIO就绪,比如socket上发生可读、可写事件。因为TCP服务器可触发SIGIO的条件很多,故而SIGIO无法在TCP服务器中用。SIGIO信号可用在UDP服务器中,但也很少见
SIGPWRSystem VTerm对于UPS的系统,当电池电量过低时,SIGPWR信号被触发
SIGSYSPOSIXCore非法系统调用
SIGUNUSEDCore保留,通常和SIGSYS效果相同

参考资料

Linux信号之signal函数
https://blog.csdn.net/lixiaogang_theanswer/article/details/80301624

Linux信号列表(下方汇总了默认动作、比如默认导致进程退出的信号)
https://blog.csdn.net/baobao8505/article/details/1115820

Linux之信号
https://www.cnblogs.com/wanghao-boke/p/11320819.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值