信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通信的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

#标准信号
C语言标准定义了6个信号。定义在signal.h头文件中。C++中对应的头文件是csignal。

  • SIGABRT - 异常中止
  • SIGFPE - 浮点异常
  • SIGILL - 无效指令
  • SIGINT - 交互的用户按键请求,默认情况下,这会导致进程终止
  • SIGSEGV - 无效内存访问
  • SIGTERM - 程序的中止请求

#发送信号

  • 在一个运行的程序的控制终端键入特定的组合键可以发送某些信号,如Ctrl-C发送SIGINT,Ctrl-Z发送SIGTSTP,Ctrl-\发送SIGQUIT
  • kill()系统调用会在权限允许的情况下向进程发送特定的信号,类似地,kill命令允许用户向进程发送信号
  • 除数为0、段错误这些异常也会产生信号(这里分别是SIGFPE和SIGSEGV,默认都会导致进程终止和核心转储)
  • 内核可以向进程发送信号告知它一个事件发生了。例如进程将数据写入一个已经关闭的管道会收到SIGPIPE信号,默认情况下会使进程关闭

#处理信号
信号处理函数可以通过signal()系统调用来设置。如果没有为一个信号设置对应的处理函数,就会使用默认的处理函数,否则信号就被进程截获并调用相应的处理函数。在没有处理函数的情况下,程序可以指定两种行为:忽略这个信号(SIG_IGN)或者用默认的处理函数(SIG_DFL)。但是有两个信号是无法被截获并处理的:SIGKILL和SIGSTOP。