signal
| 定义于头文件 <signal.h>
|
||
void (*signal( int sig, void (*handler) (int))) (int);
|
||
改变信号的处理方式 sig。根据 handler 的值,信号可以被忽略、设为默认,或者由用户定义的函数处理,该函数以 (*handler)(sig) 的方式调用。
当信号处理器被设置为一个函数且发生信号时,signal(sig, SIG_DFL) 是否会在信号处理器开始之前立即执行是由实现定义的。此外,实现可以防止某些实现定义的信号在信号处理器运行时发生。
参数
| sig | - | 要设置信号处理器的信号。它可以是一个实现定义的值,或以下值之一:
| ||||||
| handler | - | 信号处理器。必须是以下之一:
|
返回值
成功时返回之前的信号处理器,失败时返回 SIG_ERR(在某些实现中设置信号处理器可能被禁用)。
信号处理器
对安装为信号处理器的用户定义函数施加以下限制:
如果用户定义函数在处理 SIGFPE、SIGILL 或 SIGSEGV 时返回,则行为未定义。
如果信号处理器是作为 abort 或 raise 的结果被调用,而信号处理器又调用了 raise,则行为未定义。
如果信号处理器不是作为 abort 或 raise 的结果被调用(即信号处理器是 异步的),则行为未定义,如果:
- 信号处理器调用标准库中的任何函数,除了
- abort
- _Exit
- quick_exit
signal,其中第一个参数是当前处理的信号编号(异步处理器可以重新注册自身,但不能注册其他信号)。- 来自
<stdatomic.h>的原子函数,如果原子参数是无锁的 - atomic_is_lock_free(任意类型的原子参数)
进入信号处理器时,浮点环境的状态和所有对象的值都是未指定的,除了:
- 类型为
volatile sig_atomic_t - 的对象无锁原子类型的对象(自C11起)
- 通过 atomic_signal_fence (自C11起)可见的副作用
从信号处理器返回时,任何由信号处理器修改的、不是 volatile sig_atomic_t 或无锁原子(自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
引用
- C23 标准(ISO/IEC 9899:2024):
- 7.14.1.1 signal 函数(第 285-286 页)
- 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
| |