信号的分类
在Linux/Unix系统下,信号总共分为两大类,一类是最常用的标准信号,另一类是后面引入的实时信号
标准信号有默认响应机制,实时信号没有响应信号
标准信号的描述
信号 | 值 | 动作 | 说明 |
SIGHUP | 1 | A | 在控制终端上是挂起信号, 或者控制进程结束 |
SIGINT | 2 | A | 从键盘输入的中断 |
SIGQUIT | 3 | C | 从键盘输入的退出 |
SIGILL | 4 | C | 无效硬件指令 |
SIGTRAP | 5 | C | 跟踪/断点自陷 |
SIGABRT | 6 | C | 非正常终止, 可能来自 abort(3) |
SIGBUS | 7 | C | 总线错误 (不正确的内存访问) |
SIGFPE | 8 | C | 浮点运算例外 |
SIGKILL | 9 | AEF | 杀死进程信号 |
SIGUSR1 | 10 | A | 用户定义的信号 1 |
SIGSEGV | 11 | C | 无效的内存引用 |
SIGUSR2 | 12 | A | 用户定义的信号 2 |
SIGPIPE | 13 | A | 管道中止: 写入无人读取的管道 |
SIGALRM | 14 | A | 来自 alarm(2) 的超时信号 |
SIGTERM | 15 | A | 终止信号 |
SIGSTKFLT | 16 | A | 协处理器堆栈错误 |
SIGCHLD | 17 | B | 子进程结束或停止 |
SIGCONT | 18 | 继续停止的进程 | |
SIGSTOP | 19 | DEF | 停止进程 |
SIGTSTP | 20 | D | 终端上发出的停止信号 |
SIGTTIN | 21 | D | 后台进程试图从控制终端(tty)输入 |
SIGTTOU | 22 | D | 后台进程试图在控制终端(tty)输出 |
SIGURG | 23 | B | 套接口上出现 urgent 情况 (4.2 BSD) |
SIGXCPU | 24 | C | 超过了CPU时间限制 (4.2 BSD) |
SIGXFSZ | 25 | C | 超过了文件大小限制 (4.2 BSD) |
SIGVTALRM | 26 | A | 虚拟超时时钟 (4.2 BSD) |
SIGPROF | 27 | A | 系统资源定时器(Profiling timer)超时 |
SIGWINCH | 28 | B | 窗口大小调整信号 (4.3 BSD, Sun) |
SIGIO | 29 | A | I/O就绪事件 (Sys V). 等同于SIGPOLL |
SIGPWR | 30 | A | 电源无效 (System V) |
SIGSYS | 31 | C | 用错误参数调用系统例程 (SVID)等同于SIGUNUSED |
信号的动作含义
A | 缺省动作是结束进程 |
B | 缺省动作是忽略这个信号 |
C | 缺省动作是结束进程, 并且核心转储 |
D | 缺省动作是停止进程 |
E | 信号不能被捕获 |
F | 信号不能被忽略 |
信号的基础操作
写的是都需要带上该头文件#include <signal.h>
1、信号的屏蔽
sigprocmask(int how,const sigset_t *set, sigset_t *oldset);
how:操作命令字,set:当前要操作的信号集,oldset:若不填NULL,将原来阻塞信号集保留到该oldset中
1、命令操作字
SIG_BLOCK(添加阻塞)、SIG_SETMASK(替换阻塞)、SIG_UNBLOCK(解除阻塞);
2、信号集set的相关操作
sigset_t set;//定义信号集
sigemptyset(&set);//清空全部信号集
sigfillset(&set);//将所有信号加入信号集
sigaddset(&set,SIGUSR1);//添加10号信号(可指定)
sigdelset(&set,SIGUSR1)://剔除10号信号(可指定)
sigismember(&set,SIGUSR1);//检测10号信号是否在信号集中(可指定)
2、信号的捕捉
ypedefvoid (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
标准的信号相应函数接口
void func(int sig)
{
//写函数内的具体实现
}
pause();//捕获一个信号
3.信号的默认处理
如果程序没有对信号做任何预先准备,那么当信号达到时,则会按照信号的默认规则进行响应,具体默认规则可使用如下命令查阅:在ubuntu用命令man 7 signal查询
具体信号的动作含义在上述动作的含义中的表格中讲述
4、忽略信号
在使用signal()函数或类似机制设置信号处理函数时,可以将SIG_IGN作为第二个参数,以指示系统忽略指定的信号。例如,signal(SIGINT, SIG_IGN);会指示系统忽略SIGINT信号(通常由Ctrl+C产生)。
防止默认行为:
某些信号有默认的处理行为,如终止进程(如SIGKILL)或暂停进程(如SIGSTOP)。然而,对于可以被捕获或忽略的信号,设置SIG_IGN可以防止这些默认行为的发生。
处理僵尸进程:
在多进程编程中,当子进程结束时,会向父进程发送SIGCHLD信号。如果父进程不关心子进程的结束状态,可以通过signal(SIGCHLD, SIG_IGN);来忽略SIGCHLD信号,这样父进程就不会因为等待子进程结束而阻塞,同时子进程的状态也会被系统回收,避免产生僵尸进程。