分享

Linux信号之signal函数

 魅影苍穹 2020-04-08

1. 信号概述
何为信号:信号就是由用户、系统或进程发送给目标进程的信息,以通知目标进程中某个状态的改变或是异常。
信号产生:总体来说,其产生的条件有两种,分别是:硬件和软件原因,又称为:硬中断和软中断可细分为如下几种原因:
①系统终端Terminal中输入特殊的字符来产生一个信号,比如按下:ctrl + </font>会产生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。 对于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 可以查看所有的信号。
这里写图片描述
这里是上面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非法系统调用
SIGUNUSED
Core保留,通常和SIGSYS效果相同

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多