4404

22 分钟

#C 语言标准库函数 signal

/********************************************* * @brief 为指定的信号设置信号处理函数 * @param sig 要处理的信号 * @param handler 要设置的处理函数 * @return 该信号此前的处理函数 ********************************************/ void (*signal(int sig, void (*handler)(int)))(int);

可拆解为:

typedef void (handler_function)(int); handler_function* signal(int sig, handler_function* handler);

说明

将信号 sig 的处理函数设为 handler

当信号产生时,程序的的执行流程转移到信号处理函数;信号处理函数返回后,程序的的执行流程转移到原先位置继续执行。

由实现定义,在进入信号处理函数之前,通常会自动执行 signal(sig, SIG_DFL) 将信号处理函数恢复为默认。

由实现定义,未使用 signal 设置处理函数的信号产生时可能忽略(SIG_IGN)或使用默认的处理函数(SIG_DFL),通常为后者。

SIGFPESIGILLSIGSEGV 信号的处理函数必须退出程序,不能返回,否是是未定义行为。

参数

  • sig - 要处理的信号
  • handler - 要设置的处理函数,或者:
    • SIG_IGN - 表示忽略该信号
    • SIG_DFL - 表示使用默认的处理函数

返回值

  • 成功时返回信号 sig 之前的处理函数
  • 失败时返回 SIG_ERR

#示例

#include <signal.h> #include <stdio.h> void signal_handler(int sig) { printf("收到信号: %d\n", sig); // 重新设置信号的处理函数 signal(SIGINT, signal_handler); } int main(void) { // 设置信号的处理函数 signal(SIGINT, signal_handler); // 发送信号 raise(SIGINT); raise(SIGINT); raise(SIGINT); return 0; }

运行结果:

收到信号: 2 收到信号: 2 收到信号: 2

#信号列表

信号标准说明
SIGABRTC89中止
SIGFPEC89运算错误
SIGILLC89非法指令
SIGINTC89中断
SIGSEGVC89段错误
SIGTERMC89终止请求

注意:

  1. 信号在不同环境中可能有不同的具体数值
  2. 并非所有系统都支持表中的全部信号
  3. 不同环境可能定义有表中不包含的其它信号

类 UNIX 系统可以通过 kill -l 命令查看支持的信号:

user@host:~ $ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

其中常用信号如下:

  • SIGTERM - 请求进程正常退出。进程应当按部就班地清理资源并正常终止。关机过程中会触发这个信号。
  • SIGQUIT - 强力的要求进程退出。进程应当快速清理资源并退出。可以通过 Ctrl + \ 触发。
  • SIGKILL - 强制杀死进程。这个信号不能被捕获(即 signal 函数不能设置此信号的处理函数)。
  • SIGHUP - 终端挂断信号。关闭终端、退出SSH等操作会触发这个信号。
  • SIGINT - 中断信号。可以通过 Ctrl + C 触发。
  • SIGSTOP - 暂停程序执行。这个信号不能被捕获(即 signal 函数不能设置此信号的处理函数)。可以通过 Ctrl + Z 触发。
  • SIGCONT - 恢复程序执行。可以通过 fg 命令触发。

命令行程序常常使用 Ctrl + D 进行正常退出。这个命令并非发送信号,而是发送 EOF

#推荐阅读

#外部参考

#参考标准

  • C17 standard (ISO/IEC 9899:2018):
    • 7.14.1.1 The signal function (p: 193-194)
  • C11 standard (ISO/IEC 9899:2011):
    • 7.14.1.1 The signal function (p: 266-267)
  • C99 standard (ISO/IEC 9899:1999):
    • 7.14.1.1 The signal function (p: 247-248)
  • C89/C90 standard (ISO/IEC 9899:1990):
    • 4.7.1.1 The signal function

创建于 2025/10/16

更新于 2025/10/16