面试题答案
一键面试- 关键代码片段:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handle_signal(int signum) {
// 信号处理函数,这里可以不做具体处理
}
int main() {
struct sigaction sa;
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
return 1;
}
printf("SIGINT signal is now blocked. Press Ctrl+C to test.\n");
while (1) {
sleep(1);
}
return 0;
}
- 原理解释:
sigaction
函数:在Linux环境下,sigaction
函数用于改变进程接收到特定信号后的行为。它的原型为int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
。struct sigaction
结构体:sa_handler
:指定信号处理函数。在上述代码中,我们定义了handle_signal
函数,它作为SIGINT
信号的处理函数。这里即使该函数为空,也能起到屏蔽默认行为(终止进程)的作用。sa_mask
:一个信号集,在信号处理函数执行期间,这些信号会被阻塞。sigemptyset(&sa.sa_mask);
用于清空这个信号集,即处理SIGINT
信号时不额外阻塞其他信号。sa_flags
:用于指定一些选项,这里设置为0,表示使用默认选项。
sigaction
调用:sigaction(SIGINT, &sa, NULL)
将SIGINT
信号的处理方式设置为我们定义的sa
结构体中的设置。如果调用失败,sigaction
函数返回-1,并设置errno
,perror("sigaction")
用于打印错误信息。- 循环:
while (1) { sleep(1); }
用于保持程序运行,以便测试SIGINT
信号是否被正确屏蔽。当按下Ctrl + C
(产生SIGINT
信号)时,程序不会像默认情况下那样终止,而是执行我们定义的信号处理函数(这里为空)。
另一种简单方式是使用signal
函数:
- 关键代码片段:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handle_signal(int signum) {
// 信号处理函数,这里可以不做具体处理
}
int main() {
if (signal(SIGINT, handle_signal) == SIG_ERR) {
perror("signal");
return 1;
}
printf("SIGINT signal is now blocked. Press Ctrl+C to test.\n");
while (1) {
sleep(1);
}
return 0;
}
- 原理解释:
signal
函数:signal
函数是一个较为简单的设置信号处理方式的函数,原型为void (*signal(int signum, void (*func)(int)))(int);
。它将signum
信号的处理函数设置为func
。- 返回值:如果设置成功,
signal
函数返回之前的信号处理函数指针,若失败则返回SIG_ERR
,并设置errno
,perror("signal")
用于打印错误信息。这里同样定义了handle_signal
函数来处理SIGINT
信号,达到屏蔽其默认终止进程行为的目的。