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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: `<signal.h>` 是 C 标准库中的头文件,提供信号处理功能,用于通知程序特定事件,如非法操作或定时器到期。它定义了多种信号常量(如 `SIGINT`、`SIGTERM`、`SIGKILL`、`SIGSEGV`、`SIGUSR1` 和 `SIGUSR2`),并允许通过 `signal()` 或 `sigaction()` 设置信号处理函数。

<signal.h> 是 C 标准库中的一个头文件,提供了信号处理相关的功能。信号是一种异步通知,它可以通知程序发生了特定的事件,例如非法操作、定时器到期等。以下是对 <signal.h> 中主要功能的详解:

1. 常用信号常量

信号在 <signal.h> 中定义了一系列的信号常量,每个常量都表示一个特定的信号。常见的信号包括:

  • SIGINT:中断信号,通常由 Ctrl+C 触发。
  • SIGTERM:终止信号,用于请求程序终止。
  • SIGKILL:强制终止信号,无法被捕获或忽略。
  • SIGSEGV:段错误信号,表示非法内存访问。
  • SIGUSR1SIGUSR2:用户定义的信号,可以用于进程间通信。

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> 提供了处理信号的机制,使程序能够响应异步事件。通过合理使用信号机制,可以让应用程序在面对各种情况时更加健壮和灵活。

相关文章
|
存储 物联网
|
9月前
|
存储 Unix Linux
<C语言错误处理> <signal.h>头文件及signal函数等内置函数
<C语言错误处理> <signal.h>头文件及signal函数等内置函数
|
C++
boost之signal的使用
boost是C++的一个扩展库,被称为C++准标准库,里面的组件很丰富,并且引用方便,85%的组件只需要引用头文件即可使用。在嵌入式系统也可以很方便的使用,这里介绍一下signal的使用,有点类似Qt里的信号槽。 可以接收静态函数、类成员函数、labmda表达式。 下面这个是使用signal封装的一个事件注册处理模板,使用起来还是很方便的。
151 0
|
安全 算法 前端开发
【Example】C++ 标准库 std::thread 与 std::mutex
与 Unix 下的 thread 不同的是,C++ 标准库当中的 std::thread 功能更加简单,可以支持跨平台特性。 因此在应用需要跨平台的情况下,应优先考虑使用 std::thread。 同时为了使多线程操作更加安全,std::thread 经常与标准库互斥量 std::mutex 相配合使用。
388 0
|
物联网 Linux 开发者
signal 函数返回值|学习笔记
快速学习 signal 函数返回值
|
物联网 Linux 开发者
signal 函数1|学习笔记
快速学习 signal 函数1
|
5月前
|
安全
C 标准库 - <errno.h>详解
`&lt;errno.h&gt;` 是 C 标准库中的错误处理头文件,定义了全局变量 `errno` 和一系列错误代码宏,如 `ENOMEM`(内存不足)、`EINVAL`(无效参数)等,用于检测和处理函数调用中的错误。在调用可能引发错误的函数前后应检查和清零 `errno` 以准确识别错误原因。
|
8月前
|
存储 程序员 C语言
C 标准库 - <errno.h>
C 标准库 - <errno.h>
|
9月前
|
存储 安全 算法
【C++ 包装器类 std::atomic 】全面入门指南:深入理解并掌握C++ std::atomic 原子操作 的实用技巧与应用
【C++ 包装器类 std::atomic 】全面入门指南:深入理解并掌握C++ std::atomic 原子操作 的实用技巧与应用
797 1