现在位置: 首页 > C 教程 > 正文

C 库函数 - sigaction()

C 标准库 - <signal.h> C 标准库 - <signal.h>

sigaction 函数是 C 标准库中的一个函数,用于检查或修改与特定信号相关联的处理动作。与 signal 函数相比,sigaction 提供了更多的控制和更好的移植性。

语法

int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);

参数

  • int sig:要检查或修改的信号编号。常见的信号包括 SIGINTSIGTERMSIGKILL 等。
  • const struct sigaction *act:指向新的信号处理动作的指针。如果为 NULL,则不修改当前的信号处理动作。
  • struct sigaction *oldact:指向用于保存旧的信号处理动作的指针。如果为 NULL,则不保存旧的信号处理动作。

struct sigaction 结构体

struct sigaction {
    void (*sa_handler)(int);           // 信号处理函数指针
    void (*sa_sigaction)(int, siginfo_t *, void *); // 信号处理函数指针(扩展)
    sigset_t sa_mask;                  // 在处理该信号时要阻塞的信号集
    int sa_flags;                      // 修改信号行为的选项
    void (*sa_restorer)(void);         // 恢复函数,已废弃
};

sa_flags 的常见选项

  • SA_RESTART:使被信号中断的系统调用自动重新启动。
  • SA_SIGINFO:使用 sa_sigaction 而不是 sa_handler 作为信号处理函数。
  • SA_NOCLDSTOP:如果 sigSIGCHLD,则在子进程停止或继续时不产生该信号。

返回值

  • 成功时返回 0。
  • 失败时返回 -1,并设置 errno 以指示错误类型。

实例

以下是一个简单的示例程序,演示如何使用 sigaction 函数设置 SIGINT 信号的处理程序:

实例

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// 自定义的信号处理函数
void handle_sigint(int sig) {
    printf("Caught signal %d\n", sig);
}

int main() {
    struct sigaction sa;

    // 设置处理程序为 handle_sigint
    sa.sa_handler = handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    // 使用 sigaction 设置新的信号处理动作
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    // 主循环,持续运行直到捕捉到信号
    while (1) {
        printf("Running...\n");
        sleep(1);
    }

    return 0;
}

编译并运行程序后,输出将是:

Running...
Running...
Running...
...

当按下 Ctrl+C(发送 SIGINT 信号)时,输出将是:

Caught signal 2

程序捕捉到 SIGINT 信号并执行了自定义的信号处理函数 handle_sigint,然后继续运行主循环。

注意事项

  • sigaction 函数提供了比 signal 函数更丰富的功能,可以设置信号处理函数、信号掩码和信号处理选项。
  • 信号处理函数应尽量简短,因为在处理信号时会阻塞其他信号。如果信号处理函数运行时间过长,可能会影响程序的实时性。
  • 某些信号(如 SIGKILLSIGSTOP)不能被捕捉或忽略。

C 标准库 - <signal.h> C 标准库 - <signal.h>