C++ signal

ISO C标准支持的信号

信号名称 含义 默认行为
SIGABRT 异常终止信号,一般通过调用abort函数产生 terminate+core
SIGINT 中断信号,一般通过键盘输入ctrl+c产生 terminate
SIGSEGV 段错误信号,一般通过访问非法地址产生 terminate+core
SIGTERM 终止信号,kill命令默认发送该信号 terminate
SIGFPE 浮点错误信号,比如除0,浮点计算溢出等 terminate+core
SIGILL 错误指令信号 terminate+core

处理信号的三种方式

  1. 忽略信号(SIG_IGN):忽略信号,不做任何处理,但是SIGKILLSIGSTOP是不可以被忽略和捕捉的,并且最好不要忽略硬件产生的信号,否则行为未定义。
  2. 捕捉信号(sighandler):捕捉信号,执行指定的动作。
  3. 默认行为(SIG_DFL):执行信号的默认行为。

signal async safe的系统函数

可靠信号与不可靠信号

signal比sigaction简单,但signal注册的信号在sa_handler被调用之前把会把信号的sa_handler指针恢复,而sigaction注册的信号在处理信号时不会恢复sa_handler指针:

int sig_int(); /* my signal handling function */
...
signal(SIGINT, sig_int); /* establish handler */
...

sig_int()
{
    signal(SIGINT, sig_int); /* reestablish handler for next time */
}

上面的代码大部分情况可以正常运行,但一些特殊情况,比如SIGINT信号触发之后,在执行到sig_int的重置语句之前,又触发了SIGINT,这时会执行默认行为——也就是退出函数,就会有问题。
信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()以及信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。
信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。目前linux中的signal()是通过sigation()函数实现的,因此,即使通过signal()安装的信号,在信号处理函数的结尾也不必再调用一次信号安装函数。同时,由signal()安装的实时信号支持排队,同样不会丢失。

posted @ 2021-01-02 11:58  HachikoT  阅读(406)  评论(0编辑  收藏  举报