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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: `<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> 提供了处理信号的机制,使程序能够响应异步事件。通过合理使用信号机制,可以让应用程序在面对各种情况时更加健壮和灵活。

相关文章
|
Oracle 关系型数据库 Linux
CentOS7下安装TigerVNC Server
CentOS7下安装TigerVNC Server
1448 0
CentOS7下安装TigerVNC Server
|
存储 运维 监控
机器的coredump文件过多处理
【10月更文挑战第1天】
704 4
HTML中的<br>、<hr>和<pre>标签使用指南
HTML中的<br>、<hr>和<pre>标签使用指南
1292 2
|
Shell Linux API
C语言在linux环境下执行终端命令
本文介绍了在Linux环境下使用C语言执行终端命令的方法。首先,文章描述了`system()`函数,其可以直接执行shell命令并返回结果。接着介绍了更强大的`popen()`函数,它允许程序与命令行命令交互,并详细说明了如何使用此函数及其配套的`pclose()`函数。此外,还讲解了`fork()`和`exec`系列函数,前者创建新进程,后者替换当前进程执行文件。最后,对比了`system()`与`exec`系列函数的区别,并针对不同场景推荐了合适的函数选择。
|
存储 编译器 Serverless
C 标准库 - <stdarg.h>详解
`&lt;stdarg.h&gt;` 是 C 标准库中的头文件,提供了处理可变参数函数(varargs)的机制,允许开发者定义接受任意数量参数的函数。它定义了三个主要宏:`va_start`、`va_arg` 和 `va_end`,用于初始化、访问和清理可变参数列表。
|
安全 C语言
C 标准库 - <stddef.h>详解
`&lt;stddef.h&gt;` 是 C 标准库的一个头文件,定义了常用类型和宏,包括 `size_t`(表示对象大小)、`ptrdiff_t`(指针间差值)、`NULL`(空指针)和 `offsetof`(计算结构体成员偏移量)。
|
存储 网络协议 网络安全
MQTTClient_create函数
MQTTClient_create函数
822 0
|
数据采集 XML 数据挖掘
构建高效Python爬虫:探索BeautifulSoup与Requests库的协同工作
【7月更文挑战第31天】在数据驱动的世界里,掌握网络数据采集技术变得尤为重要。本文将深入探讨如何利用Python语言中的BeautifulSoup和Requests库来构建一个高效的网络爬虫。我们将通过实际案例,展示这两个库如何在爬取网页数据时相互配合,以及如何通过简单的编码实现数据的精准抓取。文章不仅提供代码示例,还讨论了在使用这些工具时应注意的一些常见陷阱和最佳实践。无论你是数据分析师、研究人员还是对爬虫技术感兴趣的程序员,这篇文章都将为你提供一个清晰的指导框架,帮助你快速入门并提高你的爬虫技能。
366 1
|
机器学习/深度学习 并行计算 编译器
AVX 指令集简介及其与 SSE 的对比
本文介绍了AVX指令集在高性能计算中的重要性,它是Intel于2011年推出的一种SIMD技术,扩展了SSE指令集,将向量宽度增至256位,支持更多数据类型和浮点精度控制。主要差异包括向量宽度、数据类型扩展、指令集增加和精度控制。文中通过C代码示例展示了如何使用AVX进行向量加法。AVX对科学计算、图像处理和机器学习等领域提供了显著的性能提升。编译时需确保编译器支持AVX标志。
|
Web App开发 前端开发 Java
Python Selenium自动化测试框架
Python Selenium自动化测试框架