Windows环境下CTRL+C信号处理函数的执行线程

1. 捕获CTRL+C

有时候我们希望自己的程序被CTRL+C以后,可以先执行一些收尾的工作才结束,比如释放动态内存,关闭网络端口、保存一些状态日志等等,可以用到C++的signal的机制。

例程如下:

#include <iostream>
#include <thread>
#include <signal.h>
#include <conio.h>
#include <Windows.h>bool exe_stop = false; // 程序结束标志位
std::thread::id sigint_id;// Ctrl+C捕获后执行的代码
void sigint_handler(int sig) 
{sigint_id = std::this_thread::get_id(); // 记录执行这个函数的线程号exe_stop = true; // 改写标志位
}int main(int argc, char **argv) 
{signal(SIGINT, sigint_handler); // 注册信号处理函数std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;while (!exe_stop){std::cout << "loop ..." << std::endl;Sleep(1000);}std::cout << "sigint thread id = " << sigint_id << std::endl;std::cout << "exe stopped!" << std::endl;// 下面就可以执行清理的操作了..._getch();return 0;
}

主要有以下几点

  • 引入头文件<signal.h>
  • 实现一个信号处理函数void function(int sig)
  • 用库函数signal注册

然后当程序运行期间,我们向终端输入CTRL+C的时候,例程sigint_handler就会执行。        

2. 信号处理函数的在哪个线程执行

OK!功能已经实现了。那么还有个疑问,究竟这个信号处理函数在哪个线程执行?因为这个问题会牵涉到在信号处理函数的实现里面我们需不需要考虑临界资源保护和死锁。

根据20次左右的测试结果来看,WINDOWS给我们开辟了一个新的线程去执行信号(CTRL+C)处理函数。在截图中,主线程ID是1148,而信号处理函数的执行线程ID是7304。为了判断这个测试结果是否具有偶然性,我查了一下资料(signal | Microsoft Learn),微软是这么说的

由此看来,实验结果和理论吻合。

3. 信号处理函数实现注意事项

再延伸一下,微软文档有对信号处理函数的实现做了一些要求,原文是这样的:

  • Don't issue low-level or STDIO.H I/O routines (for example, printf or fread).

  • Don't call heap routines or any routine that uses the heap routines (for example, malloc_strdup, or _putenv). For more information, see malloc.

  • Don't use any function that generates a system call (for example, _getcwd or time).

  • Don't use longjmp unless the interrupt is caused by a floating-point exception (that is, sig is SIGFPE). In this case, first reinitialize the floating-point package by using a call to _fpreset.

  • Don't use any overlay routines.

我的个人理解如下:

  1. 不要用底层或者标准IO函数,如printffread
  2. 不要申请堆空间(mallocnew) 
  3. 不要进行系统调用(就是要在内核态工作的库函数,一般是需要涉及到物理硬件的操作,如文件IO、内存申请、网络收发,屏幕打印)。实际上我觉得这一条涵盖了上面1和2
  4. 不要用longjmp函数
  5. 没看懂,求翻译

简而言之,信号处理函数越简单越好

4. 参考文章 

windows 平台的信号处理_window 进程有信号处理-CSDN博客

kill及kill -9的用法及如何实现进程的优雅退出_shell kill -9-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/443772.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【工具】前端js数字金额转中文大写金额

【工具】前端js数字金额转中文大写金额 代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>金额转…

WIFI网速不够是不是光猫的“路由模式”和“桥接模式”配置错了?

光猫&#xff08;光纤调制解调器&#xff09;是一种用于将光纤信号转换为数字信号的设备&#xff0c;通常用于家庭或企业网络中。光猫可以在不同的工作模式下运行&#xff0c;其中最常见的两种模式是“路由模式”和“桥接模式”。以下是这两种模式的详细解释及其优缺点。 一、路…

『网络游戏』服务器向客户端分发消息【20】

对服务器添加System引用 修改脚本&#xff1a;LoginSys.cs 修改脚本&#xff1a;NetSvc.cs 修改脚本&#xff1a;ServerSession.cs 修改脚本&#xff1a;GameMsg.cs 修改脚本&#xff1a;MsgPack.cs 修改脚本&#xff1a;LoginSys.cs 修改脚本&#xff1a;ServerRoot.cs 修改脚…

GAMES101(19节,相机)

相机 synthesis合成成像&#xff1a;比如光栅化&#xff0c;光线追踪&#xff0c;相机是capture捕捉成像&#xff0c; 但是在合成渲染时&#xff0c;有时也会模拟捕捉成像方式&#xff08;包括一些技术 动态模糊 / 景深等&#xff09;&#xff0c;这时会有涉及很多专有名词&a…

探索新境界,尽在Codigger新版官网!

&#x1f389; 重大更新&#xff01; 我们自豪地宣布 Codigger 官网焕然一新&#xff0c;带来前所未有的体验&#xff01; &#x1f31f; 全新界面&#xff1a;Desktop享受更加直观、现代的视觉盛宴&#xff0c;发现 Codigger 的无限可能。 &#x1f680; 增强功能&#xff1…

ThinkPHP5bootstrapMySQL开发学习平台(包括后台管理功能、PC端网页、移动端网页)手把手运行源码

一、项目预览(全部源码链接在最下面) 功能及页面持续优化中...... 二、本地运行方式 1、下载源码包进行解压(源码在最下面) 2、下载phpstudy_pro,并运行Apache&

【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)

文章目录 一、Qt 简介二、安装开源版本2.1 Qt 官网 与 版本选择2.2 Qt 安装程序 三、使用示例3.1 Qt Creator3.11 示例程序3.12 新建C项目3.13 新建Python项目 3.2 Visual Studio 附录附录 1&#xff1a;Additional Libraries 说明附录2 &#xff1a;老版本安装附录3&#xff1…

Java数据类型常量

目录 一、数据类型 1.1分类 1.2关键字&内存占用&范围 1.3包装类 1.4说明 1.5类型转换 1.6类型提升 二、常量 2.1java中的常量 2.2定义常量 2.3分类 一、数据类型 1.1分类 1.2关键字&内存占用&范围 数据类型关键字内存占用范围字节型byte1字节-128…

使用three.js 实现一个 马赛克得 shader

使用three.js 实现一个 马赛克得 shader 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idmosaicShader 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-cesium-example…

【大数据】数据分析之Spark框架介绍

文章目录 概述一、发展历程与背景二、核心特点三、生态系统与组件四、应用场景五、与其他大数据技术的比较 核心概念1. 弹性分布式数据集&#xff08;RDD, Resilient Distributed Dataset&#xff09;2. 转换&#xff08;Transformations&#xff09;和动作&#xff08;Actions…

【网络篇】计算机网络——应用层详述(笔记)

目录 一、应用层协议原理 1. 进入应用层 2. 网络应用程序体系结构 &#xff08;1&#xff09;客户-服务器体系结构&#xff08;client-server architecture&#xff09; &#xff08;2&#xff09; P2P 体系结构&#xff08;P2P architecture&#xff09; 3. 进程间通讯 …

Java之String类

目录 初识String 字符串比较相等 字符串常量池 理解字符串的不可变 字符与字符串 字符串常见操作 字符串比较 compareTo()函数的原码 字符串查找 字符串替换 字符串拆分 字符串截取 其它操作 StringBuffer和StringBuilder 面试题&#xff1a;请解释String、Strin…

Cocos_鼠标滚轮放缩地图

文章目录 前言一、环境二、版本一_code2.分析类属性方法详细分析详细分析onLoad()onMouseWheel(event)详细分析 总结 前言 学习笔记&#xff0c;请多多斧正。 一、环境 通过精灵rect放置脚本实现鼠标滚轮放缩地图。 二、版本一_code import { _decorator, Component, Node }…

第十一章:规划过程组(11.18规划风险管理--11.24规划干系人参与)

前面几次考试几乎都考了风险管理的相关内容和试题~&#xff01;尤其是下午题所以感觉还是挺重要的&#xff01; 11.18 规划风险管理 11.18.1 风险基本概念 每个项目都在两个层面上存在风险:一是每个项目都有会影响项目达成目标的单个风险;二是由单个风险和不确定性的其他来源联…

一文了解,ARM 工业计算机的发展历程

ARM 工业计算机的发展历程主要经历了以下几个阶段&#xff1a; 早期探索阶段&#xff08;20 世纪 80 年代 - 90 年代初&#xff09;&#xff1a; 起源背景&#xff1a;20 世纪 80 年代&#xff0c;计算机工业蓬勃发展&#xff0c;英国的 Acorn 公司在这一时期积极探索芯片技术…

VRRP协议个人理解+报文示例+典型配置-RFC2338/RFC3768/RFC5798/RFC9568

个人认为&#xff0c;理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息&#xff0c;更加便于理解协议。 因此本文将在VRRP协议报文的基础上进行介绍。 VRRP协议发展 关于VRRPv2基本原理&#xff0c;可重点参考2004年发布的RFC3768-Virtual Ro…

Qt5.15.2静态编译 MinGW with static OpenSSL

如果想用VS2017编译,可参考:Qt5.15.2静态编译 VS2017 with static OpenSSL 一.环境 系统:Windows 10 专业版 64位 编译器:MinGW 8.1.0 第三方工具:perl,ruby和python PS:经验证,用MinGW 12.1.0来编译Qt5.15.2会报错 我用Phthon 2.7.18虽然可以编过,但是强烈建议Pyth…

CSS响应式布局

CSS 响应式布局也称自适应布局&#xff0c;是 Ethan Marcotte 在 2010 年 5 月份提出的一个概念&#xff0c;简单来讲就是一个网站能够兼容多个不同的终端&#xff08;设备&#xff09;&#xff0c;而不是为每个终端做一个特定的版本。这个概念是为解决移动端浏览网页而诞生的。…

可以让你干一辈子的10大项目,想赚钱的别错过!

1、卖项目 很多想要创业、或者从事自由职业的小伙伴,都经常会因为找不到合适的项目而苦恼,所以那些即靠谱又赚钱的好项目,一直都是人们的刚性需求,而且还是可持续的需求,倘若谁能解决这个问题,那么自然就可以赚到大钱,毕竟现在原因付费买项目的大有人在! 2、卖技术 掌…

win10电脑导航栏经常卡死改善方法

我成功使用的一个方法&#xff1a;关闭资讯&#xff08;需要正版的win10&#xff0c;如果是盗版需要激活&#xff09; 有两个入口 1.在任务栏上点击右键&#xff0c;选择“资讯和兴趣”&#xff0c;然后关闭它。这可能会解决任务栏卡顿的问题 在Windows 10中&#xff0c;任务栏…