99网
您的当前位置:首页【C语言教程】【常用类库】(十二)信号处理库 - <signal.h>

【C语言教程】【常用类库】(十二)信号处理库 - <signal.h>

来源:99网

12. 信号处理库 - <signal.h>

在 C 语言中,信号处理是一个重要的机制,它允许程序在运行时响应各种异步事件。通常用于处理如中断,退出信号,以及来自操作系统或其他程序的通信信号。本章将深入探讨信号处理的基础知识和高级用法。

12.1. 基础信号处理
12.1.1. 信号概述与默认行为

信号是进程间和操作系统与进程间通信的一种机制。信号可以通知进程某些事件的发生。

  • 常见信号

    • SIGINT:中断信号(通常从键盘输入 Ctrl+C 生成)。
    • SIGTERM:终止信号,常用于请求程序正常终止。
    • SIGKILL:强制终止信号,无法被捕获或忽略。
    • SIGSEGV:段错误信号,通常由非法内存访问引发。
  • 默认行为:信号具有默认处理行为,例如终止进程、忽略信号或生成转储文件。

12.1.2. 信号处理函数:signal

signal 函数用于捕获信号并指定自定义处理行为。通过设置信号处理函数,程序可以在捕获到信号时执行特定的代码。

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

void sigint_handler(int signum) {
    printf("Caught SIGINT (signal %d). Cleaning up...\n", signum);
}

int main() {
    // 注册信号处理函数
    signal(SIGINT, sigint_handler);
    
    // 无限循环等待信号
    while (1) {
        printf("Running...\n");
        sleep(1);
    }
    
    return 0;
}

在上面的代码中,当程序收到 SIGINT 信号(通常通过 Ctrl+C 触发)时,将调用 sigint_handler 函数。

12.2. 高级信号管理
12.2.1. sigaction 的使用

sigaction 是一个更高级的信号处理接口,相较于 signal 提供了更细粒度的信号管理。

  • 基本用法:能够查看、设置信号处理的详细行为。
#include <stdio.h>
#include <signal.h>
#include <string.h>

void sigterm_handler(int signum) {
    printf("Caught SIGTERM (signal %d). Terminating gracefully...\n", signum);
}

int main() {
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = sigterm_handler;

    // 使用 sigaction 设置信号处理器
    sigaction(SIGTERM, &sa, NULL);

    // 无限循环等待信号
    while (1) {
        printf("Running...\n");
        sleep(1);
    }

    return 0;
}

在此代码中,我们使用 sigaction 来捕获并处理 SIGTERM 信号。

12.2.2. 自定义信号处理器示例

通过自定义信号处理函数,程序可以在处理信号时执行特定的清理或日志记录操作,从而确保资源得到合理释放,使程序能够正确地应对异常情况。

12.2.3. sigset_t 信号集操作

sigset_t 是用于表示信号集的数据类型。操作信号集的常用函数包括 sigemptysetsigfillsetsigaddsetsigdelsetsigismember。这些函数可以用来灵活地定制信号处理行为,例如阻塞和解除阻塞特定的信号。

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

void print_signal_set(sigset_t *set) {
    int i;
    for (i = 1; i < NSIG; i++) { // NSIG: 信号总数
        if (sigismember(set, i))
            printf("Signal %d is in the set.\n", i);
    }
}

int main() {
    sigset_t set;
    sigemptyset(&set); // 初始化空信号集

    // 添加 SIGINT 和 SIGTERM 到信号集
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGTERM);

    // 打印信号集内容
    print_signal_set(&set);

    return 0;
}

通过掌握这些技术,程序员可以更好地控制程序对信号的响应,确保程序的健壮性和可靠性。

因篇幅问题不能全部显示,请点此查看更多更全内容