当前位置: 首页 > article >正文

c语言中的信号处理:学习<signal.h>

<signal.h> 是 C 标准库的重要头文件,用于处理信号的发送与捕获,支持异步事件通知机制。以下是它的完整解读,包括信号的基础概念、常用宏与函数解析:


信号基础

信号是操作系统提供的一种进程间通信方式,用于通知进程发生了特定的事件。信号可以由操作系统、硬件或进程本身触发。

  • 信号处理机制
    • 默认动作:每种信号都有默认处理动作(如终止进程、忽略信号等)。
    • 捕获处理:通过用户自定义的信号处理函数捕获信号。
    • 忽略信号:使用 SIG_IGN 忽略信号。
    • 不可捕获/忽略信号:如 SIGKILLSIGSTOP

示例程序

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

// 全局变量,用于控制程序退出
volatile sig_atomic_t stop = 0;

// 信号处理函数
void handle_sigint(int sig) {
    printf("Caught signal %d\n", sig);
    stop = 1; // 设置退出标志
}

int main() {
    // 设置 SIGINT 信号的处理程序
    signal(SIGINT, handle_sigint);

    while (!stop) { // 检查是否退出
        printf("Running...\n");
        sleep(1);
    }

    printf("Exiting...\n");
    return 0;
}

程序说明

  • 使用 signal 函数捕获 SIGINT 信号(Ctrl+C)。
  • 定义 volatile sig_atomic_t stop,确保信号处理的线程安全性。
  • handle_sigint 是信号处理函数,捕获到信号后修改 stop 变量。
  • 主循环通过检查 stop 控制程序的退出。

运行结果

Running...
Running...
Running...
^CCaught signal 2
Exiting...

关键数据类型

  1. sig_atomic_t

    • 类型:整数类型(int)。
    • 用途:信号处理函数中用作全局变量,保证对该变量的操作是原子的。
    • 示例:
      volatile sig_atomic_t flag = 0;
      
  2. sigset_t

    • 描述:用于表示信号集的类型。
    • 常与以下函数配合使用:
      • sigemptyset:初始化为空集。
      • sigaddset:向信号集中添加信号。
      • sigdelset:从信号集中删除信号。

重要宏

描述
SIG_DFL将信号处理恢复为默认动作。
SIG_IGN忽略信号。
SIG_ERR信号处理函数设置错误时的返回值。

常见信号类型

信号名称描述默认动作
SIGABRT异常终止(由 abort 触发)。终止进程,生成核心转储。
SIGINT中断信号(如按下 Ctrl+C)。终止进程。
SIGKILL强制终止(不可捕获/忽略)。终止进程。
SIGSEGV段错误(非法内存访问)。终止进程,生成核心转储。
SIGTERM请求终止。终止进程。
SIGSTOP停止进程(不可捕获/忽略)。暂停进程。
SIGUSR1用户自定义信号 1。终止进程。
SIGUSR2用户自定义信号 2。终止进程。

常用函数

1. signal

定义

void (*signal(int sig, void (*func)(int)))(int);

功能:设置信号的处理函数。

  • sig:信号编号。
  • func:信号处理函数,可以是自定义函数或 SIG_DFL/SIG_IGN
  • 返回值:先前的信号处理函数指针。

2. raise

定义

int raise(int sig);

功能:向当前进程发送指定信号。

3. kill

定义

int kill(pid_t pid, int sig);

功能:向指定进程发送信号。

  • pid:目标进程 ID。
  • sig:信号编号。

4. 信号集操作函数

函数描述
sigemptyset初始化为空信号集。
sigfillset初始化为全信号集。
sigaddset添加信号到信号集。
sigdelset从信号集中删除信号。
sigismember检查信号是否在信号集中。

5. 高级信号函数

函数描述
sigaction设置或获取信号处理动作,比 signal 更强大。
sigprocmask阻塞或解除阻塞信号。
sigpending获取未决信号集。
sigsuspend暂时替换信号屏蔽字,并挂起进程直到信号到来。

6. 定时器与挂起函数

函数描述
alarm在指定秒数后发送 SIGALRM 信号。
pause挂起进程直到信号到来。

注意事项

  1. 线程安全性

    • 信号处理程序中应避免使用不可重入的函数(如 printf)。
    • 推荐使用 sig_atomic_t 类型的变量。
  2. 信号屏蔽

    • 使用 sigprocmask 可以防止特定信号在关键代码段被处理。
  3. 高级处理

    • 建议使用 sigaction 替代 signal,它支持更精细的控制。

http://www.kler.cn/a/442654.html

相关文章:

  • Android string.xml中特殊字符转义
  • 【51项目】51单片机自制小霸王游戏机
  • IOS界面传值-OC
  • 软件测试面试题整理
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • Android SDK下载安装(图文详解)
  • 鸿蒙元服务项目实战:备忘录UI页面开发
  • 获取github容器注册表
  • 统计字符的个数C++
  • 正则表达式在线校验(RegExp) - 加菲工具
  • 微软商店错误提示的全方位解决方案
  • Vue项目的iconfont引入
  • Go语言开发入门与实战
  • 【踩坑】pip离线+在线在虚拟环境中安装指定版本cudnn攻略
  • java二分查找算法详解
  • wireshark功能块
  • 一分钟上手:如何创建你的第一个 Spring Boot Starter
  • Python:利用蒙特卡洛方法求解圆周率
  • CSS系列(21)-- Houdini 详解
  • 【Figma_01】Figma软件初始与使用
  • C++【默认成员函数(下)】
  • C++STL之list(用法超详解)
  • 一款可以替代Navicat的数据库管理工具
  • java: 无效的目标发行版: 9或警告: 源发行版 9 需要目标发行版 9
  • android liveData更新UI数据
  • google guava 库 最佳实践 学习指南 学习实用示例