0

0

C++怎么处理信号(Signal)_C++在Unix/Linux环境下的信号处理与编程

穿越時空

穿越時空

发布时间:2025-11-25 12:30:52

|

740人浏览过

|

来源于php中文网

原创

C++通过系统API实现Unix/Linux信号处理,使用signal()或更安全的sigaction()注册处理函数,捕获如SIGINT、SIGTERM等信号,响应中断或终止请求。示例显示按下Ctrl+C触发SIGINT,调用自定义处理函数输出信息并退出;另一示例用sigaction处理SIGTERM,支持可靠信号管理。注意事项包括:仅在信号处理函数中调用异步信号安全函数,避免复杂操作,推荐设置volatile sig_atomic_t标志位,主循环中检查并响应,确保线程与异常安全。合理使用可实现程序优雅关闭与外部命令响应。

c++怎么处理信号(signal)_c++在unix/linux环境下的信号处理与编程

在Unix/Linux系统中,信号(Signal)是一种用于进程间通信的机制,常用于通知进程发生了某种事件,比如用户按下Ctrl+C、程序出现段错误、定时器超时等。C++本身没有内置的信号处理机制,但可以借助操作系统提供的API来实现信号的捕获和响应。下面介绍C++在Linux环境下如何处理信号。

信号的基本概念

信号是软件中断,由内核或进程发送给另一个进程,表示某个特殊事件的发生。每个信号都有一个唯一的编号和默认行为,例如终止进程、暂停执行或忽略。常见的信号包括:
  • SIGINT:用户按下Ctrl+C,通常用于中断程序
  • SIGTERM:请求进程终止,可被捕获和处理
  • SIGKILL:强制终止进程,不能被捕获或忽略
  • SIGSEGV:段错误,访问非法内存时触发
  • SIGALRM:定时器超时信号

使用signal()函数注册信号处理器

最简单的方式是使用signal()函数设置信号处理函数。该函数定义在头文件中。

示例:捕获SIGINT信号(Ctrl+C)

#include 
#include 
#include 

void signalHandler(int sig) {
    std::cout << "\n接收到信号 " << sig << ",正在退出...\n";
    exit(sig);
}

int main() {
    // 注册SIGINT信号处理函数
    signal(SIGINT, signalHandler);

    std::cout << "等待信号(按 Ctrl+C 中断)...\n";
    while (true) {
        // 模拟工作
    }
    return 0;
}
运行程序后,按下Ctrl+C会触发SIGINT,调用signalHandler函数而不是直接终止程序。

使用sigaction进行更安全的信号处理

相比signal()sigaction提供了更精确和可靠的控制,推荐在生产环境中使用。

示例:使用sigaction处理SIGTERM

腾讯AI 开放平台
腾讯AI 开放平台

腾讯AI开放平台

下载
#include 
#include 
#include 

void signalHandler(int sig) {
    if (sig == SIGTERM) {
        std::cout << "收到终止请求,清理资源并退出。\n";
    }
    exit(0);
}

int main() {
    struct sigaction sa;
    std::memset(&sa, 0, sizeof(sa));
    sa.sa_handler = signalHandler;
    sigemptyset(&sa.sa_mask);  // 不阻塞其他信号
    sa.sa_flags = 0;

    if (sigaction(SIGTERM, &sa, nullptr) == -1) {
        perror("sigaction");
        return 1;
    }

    std::cout << "程序运行中,尝试使用 'kill ' 发送SIGTERM\n";
    while (true) {}
    return 0;
}
sigaction的优点包括:
  • 避免信号处理函数被重置为默认行为
  • 可指定阻塞哪些信号在处理期间不被接收
  • 支持更多标志位控制行为

信号处理中的注意事项

虽然信号处理很强大,但在C++中使用时需注意以下几点:
  • 信号处理函数中只能调用异步信号安全函数(如write_exit),不能使用std::coutmallocprintf等非安全函数
  • 避免在信号处理中做复杂操作,建议只设置标志位,主循环中检查并响应
  • 不要在信号处理函数中抛出异常或调用C++异常机制,行为未定义
  • 某些信号如SIGSEGV不能安全恢复,处理后应尽快退出

推荐做法:在信号处理函数中仅修改一个volatile sig_atomic_t变量,主程序循环中检查该变量。

立即学习C++免费学习笔记(深入)”;

volatile sig_atomic_t signalReceived = 0;

void signalHandler(int sig) {
    signalReceived = sig;  // 安全赋值
}

int main() {
    signal(SIGINT, signalHandler);
    while (!signalReceived) {
        // 正常工作
    }
    std::cout << "程序被信号 " << signalReceived << " 中断\n";
    return 0;
}
基本上就这些。C++通过系统调用支持信号处理,关键在于理解信号的异步性和安全限制。合理使用能提升程序健壮性,比如优雅关闭服务、响应外部控制命令等。

相关专题

更多
printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

72

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

280

2023.11.28

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1347

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

701

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

294

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

776

2023.07.05

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7万人学习

Git 教程
Git 教程

共21课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号