MST

星途 面试题库

面试题:C语言中如何屏蔽特定信号

在Linux环境下使用C语言编程,描述如何屏蔽SIGINT信号(键盘中断信号),请给出关键代码片段并解释其原理。
10.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 关键代码片段
#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;
}
  1. 原理解释
    • 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,并设置errnoperror("sigaction")用于打印错误信息。
    • 循环while (1) { sleep(1); }用于保持程序运行,以便测试SIGINT信号是否被正确屏蔽。当按下Ctrl + C(产生SIGINT信号)时,程序不会像默认情况下那样终止,而是执行我们定义的信号处理函数(这里为空)。

另一种简单方式是使用signal函数:

  1. 关键代码片段
#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;
}
  1. 原理解释
    • signal函数signal函数是一个较为简单的设置信号处理方式的函数,原型为void (*signal(int signum, void (*func)(int)))(int);。它将signum信号的处理函数设置为func
    • 返回值:如果设置成功,signal函数返回之前的信号处理函数指针,若失败则返回SIG_ERR,并设置errnoperror("signal")用于打印错误信息。这里同样定义了handle_signal函数来处理SIGINT信号,达到屏蔽其默认终止进程行为的目的。