<signal.h>
是 C 标准库中的一个头文件,提供了信号处理相关的功能。信号是一种异步通知,它可以通知程序发生了特定的事件,例如非法操作、定时器到期等。以下是对 <signal.h>
中主要功能的详解:
1. 常用信号常量
信号在 <signal.h>
中定义了一系列的信号常量,每个常量都表示一个特定的信号。常见的信号包括:
SIGINT
:中断信号,通常由 Ctrl+C 触发。SIGTERM
:终止信号,用于请求程序终止。SIGKILL
:强制终止信号,无法被捕获或忽略。SIGSEGV
:段错误信号,表示非法内存访问。SIGUSR1
和SIGUSR2
:用户定义的信号,可以用于进程间通信。
2. 信号处理函数
程序可以定义自己的信号处理函数。当信号到达时,系统会调用该函数。可以使用 signal()
函数或者 sigaction()
函数来设置信号处理函数。
使用 signal()
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void signal_handler(int signal) {
printf("Caught signal %d\n", signal);
exit(1);
}
int main() {
signal(SIGINT, signal_handler); // 捕获 Ctrl+C
while (1) {
printf("Running...\n");
sleep(1);
}
return 0;
}
使用 sigaction()
sigaction()
提供了更强大的信号处理功能,如设置信号掩码等。
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler(int signal) {
printf("Caught signal %d\n", signal);
exit(1);
}
int main() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = signal_handler; // 设置处理函数
sigaction(SIGINT, &sa, NULL); // 捕获 Ctrl+C
while (1) {
printf("Running...\n");
sleep(1);
}
return 0;
}
3. 信号的屏蔽与管理
程序可以通过信号掩码来控制哪些信号在特定时刻是被屏蔽的。可以使用 sigprocmask()
和 sigsuspend()
来管理信号掩码。
示例
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void signal_handler(int signal) {
printf("Caught signal %d\n", signal);
}
int main() {
signal(SIGINT, signal_handler);
sigset_t newmask, oldmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
sigprocmask(SIG_BLOCK, &newmask, &oldmask); // 屏蔽 SIGINT
printf("SIGINT blocked. Press Ctrl+C...\n");
sleep(5); // 在这里等候,但 SIGINT 被屏蔽
sigprocmask(SIG_SETMASK, &oldmask, NULL); // 解除屏蔽
printf("SIGINT unblocked. You can press Ctrl+C now.\n");
while (1) {
sleep(1); // 程序运行
}
return 0;
}
4. 信号的安全性
在信号处理程序中要注意不安全的操作,例如不应在信号处理程序中调用非异步信号安全的函数(如 printf()
)。推荐在信号处理程序中只执行简单的操作,如设置标志位,结束程序,或使用异步信号安全的函数。
结论
<signal.h>
提供了处理信号的机制,使程序能够响应异步事件。通过合理使用信号机制,可以让应用程序在面对各种情况时更加健壮和灵活。