signal

来自cppreference.com
< c‎ | program
定义于头文件 <signal.h>
void (*signal( int sig, void (*handler) (int))) (int);

设置信号 sig 的错误处理函数。能设置错误处理函数,使得将出现默认处理、忽略信号或调用用户定义函数。

当设置信号处理为一个函数,而信号出现时,是否立即在信号处理函数开始前调用 signal(sig, SIG_DFL) 是实现定义的。而且,实现能阻止某个实现定义的信号集在信号处理函数运行时出现。

参数

sig - 设置给信号处理函数的信号。能为实现定义的值或下列值之一:
定义信号类型
(宏常量)


handler - 信号处理函数。必须是下列之一:
  • SIG_DFL 宏。将信号处理函数默认设为默认信号处理函数。
  • SIG_IGN 宏。忽略信号。
  • 函数指针。函数签名必须等价于如下形式:
void fun(int sig);

返回值

成功时为之前设置的信号处理,失败时为 SIG_ERR (一些实现上能禁用设置信号处理函数)。

信号处理函数

安装为信号处理函数的用户定义函数上,强制了下列限制。

若用户定义函数在处理 SIGFPESIGILLSIGSEGV 时返回,则行为未定义。

若作为 abortraise 的结果调用了信号处理函数,则若信号处理函数调用 raise ,则行为未定义。

若信号处理函数不是作为 abortraise 的结果调用(换言之,信号处理是异步的),则在下列场合行为未定义

  • 信号处理在调用任何标准库内的函数,除了
  • abort
  • _Exit
  • quick_exit
  • 以当前处理信号的编号为第一参数,调用 signal (异步处理函数能重注册其自身,但不能注册其他信号)。
  • 来自 stdatomic.h 的原子函数,若原子参数为免锁
  • atomic_is_lock_free (以任何类型的原子参数)
  • 信号处理函数使用任何拥有静态或线程局域 (C11 起)存储期,且非免锁原子 (C11 起)对象,除了赋值给静态 volatile sig_atomic_t 对象。

进入信号处理函数时,浮点环境状态和所有对象的值是未指定的,除了

从信号处理函数返回时,信号处理函数所修改的任何对象的值,除了 volatile sig_atomic_t 及免锁原子 (C11 起)对象,均为未定义。

signal 被用于多线程程序,则行为未定义。不要求它是线程安全的。

注意

POSIX 要求 signal 是线程安全的,并 异步信号安全( async-signal-safe )库函数列表中的函数能从任何信号处理函数调用。

除了 abortraise 后, POSIX 还指定 killpthread_kill 以及 sigqueue 生成同步信号。

POSIX 推荐用 sigaction 替代 signal ,因为其受指定的行为,还有其关乎在执行信号处理函数时投递信号的重要实现变更。

示例

#include <signal.h>
#include <stdio.h>
 
volatile sig_atomic_t gSignalStatus;
 
void signal_handler(int signal)
{
  gSignalStatus = signal;
}
 
int main(void)
{
  signal(SIGINT, signal_handler);
 
  printf("SignalValue: %d\n", gSignalStatus);
  printf("Sending signal: %d\n", SIGINT);
  raise(SIGINT);
  printf("SignalValue: %d\n", gSignalStatus);
}

输出:

SignalValue: 0
Sending signal: 2
SignalValue: 2

引用

  • 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

参阅

运行特定信号的信号处理函数
(函数)