Namespaces
Variants

signal

From cppreference.net
定义于头文件 <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 (在某些实现中设置信号处理器可能被禁用)。

信号处理器

作为信号处理程序安装的用户自定义函数需遵循以下限制。

如果用户定义函数在处理 SIGFPE SIGILL SIGSEGV 时返回,其行为是未定义的。

如果信号处理程序是由于 abort raise 的调用而被触发,那么当信号处理程序内部调用 raise 时,其行为是未定义的。

如果信号处理器的调用并非由于 abort raise 引起(换言之,信号处理器是 异步的 ),那么以下情况的行为是未定义的:

  • 信号处理程序调用标准库中的任何函数,除了
  • 信号处理程序引用任何具有静态 或线程局部 (C11 起) 存储期 的非无锁 原子 对象 (C11 起) ,但通过赋值给静态 volatile sig_atomic_t 的情况除外。

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

从信号处理程序返回时,被信号处理程序修改且非 volatile sig_atomic_t 或非无锁原子 (since C11) 的任何对象的值是未定义的。

在多线程程序中使用 signal 会导致未定义行为。该函数不要求具备线程安全性。

注释

POSIX要求 signal 具备线程安全性,并 明确规定了一系列异步信号安全库函数 ,这些函数可以从任何信号处理程序中调用。

除了 abort raise 之外,POSIX 规范还规定 kill pthread_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

参考文献

  • C17 标准 (ISO/IEC 9899:2018):
  • 7.14.1.1 signal 函数 (页码: 193-194)
  • C11 标准 (ISO/IEC 9899:2011):
  • 7.14.1.1 signal 函数 (页码: 266-267)
  • C99标准(ISO/IEC 9899:1999):
  • 7.14.1.1 signal函数(页码:247-248)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 4.7.1.1 signal 函数

参见

运行特定信号对应的信号处理程序
(函数)
C++ 文档 关于 signal