<signal.h>
是 C 标准库中的一个头文件,用于处理程序中的信号。信号是一种异步通知机制,通常用于在程序中发生特定事件时进行中断、暂停或其他处理。通过 <signal.h>
,程序可以设置对不同信号的处理方式,如忽略信号、捕获信号并处理,或执行默认的操作。
📖 目录
1️⃣ <signal.h>
简介
- 作用:
<signal.h>
提供了信号处理的功能,允许程序捕获并响应操作系统发送的信号。信号通常用于通知程序一些事件发生,例如用户中断、非法操作、定时器到期等。 - 常见应用:中断处理、程序终止、错误处理、定时任务。
2️⃣ 常见信号处理函数
<signal.h>
定义了几种常用的信号处理函数,主要是用来设置信号的处理方式。
📌 signal
signal
函数用于定义信号的处理方式。
原型:
void (*signal(int signum, void (*handler)(int)))(int);
- 参数:
signum
:信号编号。handler
:信号处理函数的指针,指定如何处理信号。可以是:- 一个函数的指针,该函数会在信号发生时执行。
SIG_IGN
,表示忽略该信号。SIG_DFL
,表示执行信号的默认处理方式(例如,程序终止)。
- 返回值:返回前一个信号处理器的地址,如果发生错误返回
SIG_ERR
。
📌 raise
raise
函数用于向程序自身发送信号。
原型:
int raise(int signum);
- 参数:
signum
:要发送的信号的编号。 - 返回值:如果信号成功发送,返回
0
;如果发送失败,返回非零值
。
📌 abort
abort
函数用于强制程序中止,通常用于错误处理。
原型:
void abort(void);
- 返回值:该函数不会返回,程序会立即终止。
3️⃣ 常见信号类型
C 标准库中的信号类型通常与操作系统事件相关,常见的信号包括:
信号名称 | 描述 |
---|---|
SIGINT | 用户中断信号(通常由 Ctrl+C 触发)。 |
SIGTERM | 程序终止信号,通常用于请求程序正常退出。 |
SIGSEGV | 段错误(访问非法内存区域时触发)。 |
SIGFPE | 算术错误信号(如除以零或溢出)。 |
SIGILL | 非法指令信号,通常表示程序执行了不合法的机器指令。 |
SIGABRT | 调用 abort 函数时触发的信号,程序异常终止。 |
SIGBUS | 总线错误信号(如访问未对齐的内存)。 |
SIGKILL | 强制终止信号,不能被捕获、阻塞或忽略,通常用于系统级别的强制终止。 |
SIGSTOP | 暂停信号,程序可以被暂停,但不能被捕获、忽略或处理。 |
SIGCONT | 恢复信号,用于恢复被暂停的进程。 |
4️⃣ 信号处理机制
信号处理机制包括以下几个关键点:
📌 信号的发送与接收
信号是由操作系统发送的,当程序发生特定的事件时,操作系统会生成一个信号并发送给程序。程序可以通过信号处理函数捕获这些信号并采取相应的行动。
📌 信号的处理方式
信号可以通过以下方式进行处理:
- 忽略信号:通过
SIG_IGN
忽略信号。 - 执行默认处理:通过
SIG_DFL
执行信号的默认处理行为(如程序终止)。 - 自定义处理函数:使用
signal
函数指定自定义的信号处理函数。
📌 信号的阻塞与解除阻塞
信号可以在程序的某些部分被阻塞,防止在临界区域内信号的处理。可以使用 sigprocmask
等函数来设置信号的阻塞状态。
5️⃣ 示例代码
📌 示例:捕获 SIGINT
信号
该示例演示了如何使用 signal
函数捕获 SIGINT
信号并进行处理。
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void signal_handler(int signum) {
printf("Received signal %d, terminating gracefully...\n", signum);
exit(0);
}
int main() {
// 捕获 SIGINT 信号(Ctrl+C)
signal(SIGINT, signal_handler);
printf("Program is running. Press Ctrl+C to terminate.\n");
while (1) {
// 程序持续运行,等待信号
}
return 0;
}
输出:
Program is running. Press Ctrl+C to terminate.
Received signal 2, terminating gracefully...
解释:
- 使用
signal(SIGINT, signal_handler)
捕获SIGINT
信号(通常是按Ctrl+C
产生的信号)。 - 当用户按下
Ctrl+C
时,程序会调用signal_handler
函数并优雅地终止。
📌 示例:使用 raise
发送信号
该示例展示了如何使用 raise
函数向程序自身发送信号。
#include <stdio.h>
#include <signal.h>
void signal_handler(int signum) {
printf("Received signal %d\n", signum);
}
int main() {
// 捕获 SIGUSR1 信号
signal(SIGUSR1, signal_handler);
// 发送 SIGUSR1 信号
raise(SIGUSR1);
return 0;
}
输出:
Received signal 10
解释:
- 使用
signal(SIGUSR1, signal_handler)
捕获SIGUSR1
信号。 - 通过
raise(SIGUSR1)
向程序发送SIGUSR1
信号,触发signal_handler
函数。
6️⃣ 参考资料
📖 C 标准库官方文档 – signal.h
📖 GNU C Library – signal.h
📖 ISO C 标准(PDF)
📌 总结
<signal.h>
提供了信号处理的机制,允许程序捕获、发送信号以及自定义信号的处理方式。信号是程序中用于处理异步事件的一种重要工具,如程序中断、错误处理、定时任务等。通过设置信号处理函数,程序可以根据不同的信号采取适当的行动,如错误恢复、资源清理等。
发表回复