signal函数梳理

1、信号本质
信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。使用kill -l就会显示出linux支持的信号列表。其中列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。注意事项:编号为0的信号量相当于一个PING 信号,用于检查进程是否存在。

2、信号来源
硬件:在终端按下按键;或硬件异常产生信号
软件:在终端调用kill命令;进程调用kill或sigqueue函数发送信号

3、进程对信号的响应
a>捕捉信号:对于要捕捉的信号,可以为其指定信号处理函数,信号发生时该函数自动被调用,在该函数内部实现对该信号的处理。
b>忽略信号:大多数信号都可使用这种方式进行处理,但是SIGKILL和SIGSTOP这两个信号不能被忽略,同时这两个信号也不能被捕获和阻塞。此外,如果忽略某某些由硬件异常产生的信号(如非法存储访问或除以0),则进程的行为是不可预测的。
c>按照系统默认方式处理。大部分信号的默认操作是终止进程,且所有的实时信号的默认动作都是终止进程。

4、各种信号的默认处理情况
程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP
不能恢复至默认动作的信号有:SIGILL,SIGTRAP
默认会导致进程流产的信号有:SIGABRT、SIGBUS、SIGFPE、SIGILL、SIGIOT、SIGQUIT、SIGSEGV、SIGTRAP、SIGXCPU、SIGXFSZ
默认会导致进程退出的信号有:SIGALRM、SIGHUP、SIGINT、SIGKILL、SIGPIPE、SIGPOLL、SIGPROF、SIGSYS、SIGTERM、SIGUSR1、SIGUSR2、SIGVTALRM
默认会导致进程停止的信号有:SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU
默认进程忽略的信号有:SIGCHLD、SIGPWR、SIGURG、SIGWINCH

5、相关函数
代码段如下:

#include<signal.h>
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler); //signum表示所要处理的信号类型,handler描述信号关联动作

handler可取值为SIG_IGN(忽略该信号)、SIG_DFL(恢复对信号的系统默认处理)和sighandler_t类型的函数指针的三种方式,第三种方式需要在signal()被调用前申明一个上述的sighandler_t的函数,当接收到一个类型为sig的信号时,就会执行handler所指定的函数。
signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。

6、信号列表
在Linux系统中输入kill -l可以查询signal列表,对传统UNIX支持的信号进行梳理,见下:
1 SIGHUP 终端的挂断或进程死亡
2 SIGINT 来自键盘的中断信号(CTRL+C)
3 SIGQUIT 来自键盘的离开信号
4 SIGILL 非法指令
5 SIGTRAP 断点指令或其他trap指令产生
6 SIGABRT 来自abort的异常信号
7 SIGBUS 非法地址, 包括内存地址对齐(alignment)出错
8 SIGFPE 致命算术运算错误,如浮点、溢出等
9 SIGKILL 立即结束程序,本信号不能被阻塞、处理和忽略
10 SIGUSR1 留给用户使用
11 SIGSEGV 可能存在特定条件下的非法内存访问
12 SIGUSR2 留给用户使用
13 SIGPIPE 管道破裂:在读管道未打开或意外终止时往管道里写,写进程会收到此信号
14 SIGALRM 时钟定时信号,计算实际的时间或时钟时间
15 SIGTERM 程序结束信号,要求程序自己正常退出
16 SIGSTKFLT
17 SIGCHLD 子进程结束时,父进程会收到该信号
18 SIGCONT 让一个停止的(STOPPED)进程继续执行,本信号不能被阻塞
19 SIGSTOP 停止(STOPPED)进程的执行. 它和terminate以及interrupt的区别:该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.
20 SIGSTP 停止(STOPPED)进程的运行,但该信号可以被处理和忽略,来自键盘CTRL+Z
21 SIGTTIN 后台进程读终端
22 SIGTTOU 后台进程写终端
23 SIGURG out-of-band数据或“紧急”数据
24 SIGXCPU CPU时间超限
25 SIGXFSZ 文件资源大小超限
26 SIGVTALRM 虚拟时钟信号,计算该进程占用CPU的时间
27 SIGPROF 包括该进程用的CPU时间及系统调用时间(统计分布图用计时)
28 SIGWINCH 窗口大小改变
29 SIGIO 文件描述符准备就绪,可以开始进行输入/输出操作 ?
30 SIGPWR Power Failure
31 SIGSYS 非法系统调用

但注意,它与Linux系统中signum-generic.h中部分信号对应的值不同。注意区分

#ifndef	_BITS_SIGNUM_GENERIC_H
#define _BITS_SIGNUM_GENERIC_H 1

#ifndef _SIGNAL_H
#error "Never include <bits/signum-generic.h> directly; use <signal.h> instead."
#endif

/* Fake signal functions.  */

#define	SIG_ERR	 ((__sighandler_t) -1)	/* Error return.  */
#define	SIG_DFL	 ((__sighandler_t)  0)	/* Default action.  */
#define	SIG_IGN	 ((__sighandler_t)  1)	/* Ignore signal.  */

#ifdef __USE_XOPEN
# define SIG_HOLD ((__sighandler_t) 2)	/* Add signal to hold mask.  */
#endif

/* We define here all the signal names listed in POSIX (1003.1-2008);
   as of 1003.1-2013, no additional signals have been added by POSIX.
   We also define here signal names that historically exist in every
   real-world POSIX variant (e.g. SIGWINCH).

   Signals in the 1-15 range are defined with their historical numbers.
   For other signals, we use the BSD numbers.
   There are two unallocated signal numbers in the 1-31 range: 7 and 29.
   Signal number 0 is reserved for use as kill(pid, 0), to test whether
   a process exists without sending it a signal.  */

/* ISO C99 signals.  */
#define	SIGINT		2	/* Interactive attention signal.  */
#define	SIGILL		4	/* Illegal instruction.  */
#define	SIGABRT		6	/* Abnormal termination.  */
#define	SIGFPE		8	/* Erroneous arithmetic operation.  */
#define	SIGSEGV		11	/* Invalid access to storage.  */
#define	SIGTERM		15	/* Termination request.  */

/* Historical signals specified by POSIX. */
#define	SIGHUP		1	/* Hangup.  */
#define	SIGQUIT		3	/* Quit.  */
#define	SIGTRAP		5	/* Trace/breakpoint trap.  */
#define	SIGKILL		9	/* Killed.  */
#define SIGBUS		10	/* Bus error.  */
#define	SIGSYS		12	/* Bad system call.  */
#define	SIGPIPE		13	/* Broken pipe.  */
#define	SIGALRM		14	/* Alarm clock.  */

/* New(er) POSIX signals (1003.1-2008, 1003.1-2013).  */
#define	SIGURG		16	/* Urgent data is available at a socket.  */
#define	SIGSTOP		17	/* Stop, unblockable.  */
#define	SIGTSTP		18	/* Keyboard stop.  */
#define	SIGCONT		19	/* Continue.  */
#define	SIGCHLD		20	/* Child terminated or stopped.  */
#define	SIGTTIN		21	/* Background read from control terminal.  */
#define	SIGTTOU		22	/* Background write to control terminal.  */
#define	SIGPOLL		23	/* Pollable event occurred (System V).  */
#define	SIGXCPU		24	/* CPU time limit exceeded.  */
#define	SIGXFSZ		25	/* File size limit exceeded.  */
#define	SIGVTALRM	26	/* Virtual timer expired.  */
#define	SIGPROF		27	/* Profiling timer expired.  */
#define	SIGUSR1		30	/* User-defined signal 1.  */
#define	SIGUSR2		31	/* User-defined signal 2.  */

/* Nonstandard signals found in all modern POSIX systems
   (including both BSD and Linux).  */
#define	SIGWINCH	28	/* Window size change (4.3 BSD, Sun).  */

/* Archaic names for compatibility.  */
#define	SIGIO		SIGPOLL	/* I/O now possible (4.2 BSD).  */
#define	SIGIOT		SIGABRT	/* IOT instruction, abort() on a PDP-11.  */
#define	SIGCLD		SIGCHLD	/* Old System V name */

/* Not all systems support real-time signals.  bits/signum.h indicates
   that they are supported by overriding __SIGRTMAX to a value greater
   than __SIGRTMIN.  These constants give the kernel-level hard limits,
   but some real-time signals may be used internally by glibc.  Do not
   use these constants in application code; use SIGRTMIN and SIGRTMAX
   (defined in signal.h) instead.  */
#define __SIGRTMIN	32
#define __SIGRTMAX	__SIGRTMIN

/* Biggest signal number + 1 (including real-time signals).  */
#define _NSIG		(__SIGRTMAX + 1)

#endif /* bits/signum-generic.h.  */

参考:
1、L007Linux信号、信号处理和信号处理函数
2、linux下signal()函数超详细介绍

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值