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

news2024/11/24 21:05:08

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.coloradmin.cn/o/2203117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端视角下的状态机范式

状态机范式及状态管理 前言 随着产品迭代、业务量和需求量的增加&#xff0c;通常系统平台会出现代码逻辑复杂、状态混乱、维护成本增加等现象。 做同一个需求&#xff0c;最开始可能只需一天完成&#xff0c;经过长期迭代后&#xff0c;修改一个小点就可能花上两三天甚至更…

‌美国加勒比烈火波本混合威士忌新品发布会盛大举行‌

近日&#xff0c;美国知名威士忌品牌GARBBEN BLAZE加勒比烈火在北京举行了一场别开生面的新品发布会&#xff0c;正式推出了其最新力作——加勒比烈火波本混合威士忌。此次发布会吸引了众多威士忌爱好者、行业专家代表前来见证这一重要时刻。 加勒比烈火波本威士忌作为GARBBEN …

SSH 公钥认证:从gitlab clone项目repo到本地

这篇文章的分割线以下文字内容由 ChatGPT 生成&#xff08;我稍微做了一些文字上的调整和截图的补充&#xff09;&#xff0c;我review并实践后觉得内容没有什么问题&#xff0c;由此和大家分享。 假如你想通过 git clone git10.12.5.19:your_project.git 命令将 git 服务器上…

【Golang】Go语言Seeker接口与文件断点续传实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

kubelet PLEG 实现

概述 kubelet的主要作用是确保pod状态和podspec保持一致&#xff0c;这里的pod状态包括pod中的container状态&#xff0c;个数等。 为了达到这个目的&#xff0c;kubelet需要从多个来源watch pod spec的变化&#xff0c;并周期从container runtime获取最新的container状态。比如…

【Linux:线程锁】

目录 锁的接口&#xff1a; ​编辑 关于锁的几个问题&#xff1a; 从底层实现理解锁&#xff1a; 锁的接口&#xff1a; pthread_mutex_lock函数申请锁成功后&#xff0c;会返回&#xff0c;申请失败&#xff0c;函数不返回&#xff0c;继续申请&#xff0c;线程阻塞pthrea…

python33_数字格式化

数字格式化 数字格式输出说明3.1415926{:.2f}3.14保留小数点后两位3.1415926{:.2f}3.14带符号保留小数点后2位3.1415926{:.0f}3不带小数&#xff0c;但是会四舍五入5{:0>2d}05数字补0&#xff0c;填充左边&#xff0c;宽度为25{:x<4d}5xxx数字补x&#xff0c;填充右边&a…

IPv6 DAD和地址解析实验

实验目的 1、 观察并分析IPv6 DAD过程 2、 观察并分析IPv6地址解析过程 实验拓扑 实验步骤 1、观察并分析IPv6 DAD过程 在AR1的G0/0/0开启抓包。AR1的G0/0/0接口配置ipv6地址2012::1/64。在接口配置ipv6地址后&#xff0c;ipv6有一段称为Tentative生命期&#xff0c;在该阶…

Sql Server 生成脚本中的快速删除空行问题

使用 Sql Server 生成脚本&#xff0c;例如生成存储过程&#xff0c;常常会因为存在大量没用的空行。如下图5w行的脚本&#xff0c;空行很多无用&#xff0c;需要删除。 手动删除很麻烦&#xff0c;想通过快捷方法删除这些空行&#xff0c;方法其实很简单&#xff01; 1、使用…

Vue集成echarts实现统计图表

目录 一、概述 二、Vue实现echarts图表模版 三、测试运行项目 一、概述 官网地址&#xff1a;https://echarts.apache.org/examples/zh/index.html 目前的官网的echarts例子比较古老&#xff0c;如果集成Vue里面需要进行修改&#xff0c;所以可以新建一个Vue的项目代码&am…

不同类型的 LLM 有什么区别

LLM 有不同类型的模型&#xff0c;例如 Base 和 Instruct&#xff0c;他们有什么区别呢&#xff0c;Base 模型是基于原始语料进行训练的模型&#xff0c;生成结果时会持续生成&#xff0c;直到达到最大长度。而指令模型是经过问答数据集进行训练的&#xff0c;回答是会根据上下…

【AI大模型】关于ToB垂直领域大模型的一点探索和尝试

本文分享了物流技术团队在垂直领域大模型开发和部署过程中的技术细节、挑战解决策略以及实际应用案例。 ‍ 背景 大家好&#xff0c;我们是淘天物流技术团队&#xff0c;在过去一年多的实践工作中&#xff0c;我们团队围绕“物流体验”这一垂直领域&#xff0c;尝试通过垂直…

大坝渗流监测设备——渗压计

渗压计是一种用于监测大坝等水工建筑物渗流压力的重要设备&#xff0c;其准确性和可靠性对于保障大坝安全运行至关重要。南京峟思将为大家详细介绍渗压计的工作原理、安装方法及其在大坝渗流监测中的应用。 渗压计主要利用振弦频率的变化来测量渗透水压力。设备由透水部件、感应…

使用UDP网络型灯光协议控制器控制DMX512步进电机

目录 1、硬件介绍 &#xff08;1&#xff09;灯光控制器 &#xff08;2&#xff09;步进电机 &#xff08;3&#xff09;接线图 &#xff08;4&#xff09;多路步进电机DMX接线 2、调试软件测试 &#xff08;1&#xff09;软件界面 &#xff08;2&#xff09;控制器ip地…

今夜无眠!Model 2来猎杀国产新能源了

文 | AUTO芯球 作者 | 雷慢 10月11日国内新能源车企注定会有一个不眠夜&#xff0c; 为什么啊&#xff0c;马斯克已经放出狠话了&#xff0c; 10月10日&#xff08;美东时间&#xff09;的发布会“将载入史册”&#xff0c; 别不信啊&#xff0c;据说这次会发布三款车&…

AI测试入门:向量数据库 知识图谱的适用场景

AI测试入门:向量数据库 & 知识图谱的适用场景 1. 向量数据库概述2. 知识图谱概述3. 适用场景分析3.1 使用向量数据库的场景3.2 使用知识图谱的场景4. 案例分析4.1 搜索引擎中的应用4.2 医疗健康领域的应用4.3 社交媒体平台中的应用4.4 供应链管理中的应用总结1. 向量数据库…

其他浏览器可以联网,但edge不能联网

问题描述&#xff1a; 今早edge无法上网&#xff0c;检测网络连接正常&#xff0c;而且其他chrome&#xff0c;Firefox和360浏览器都可以上网。 解决方案&#xff1a; 注意&#xff1a;为防止是代理问题&#xff0c;可以在扩展中禁用后再试试 如果没有代理或者禁用代理也不…

AIOps探索 | AI与人类协作:未来IT运维应急响应的新模式

内容来源于--布博士&#xff08;擎创科技产品解决方案专家&#xff09; 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;如同一场汹涌澎湃的浪潮&#xff0c;席卷着各个行业领域&#xff0c;IT 运维应急响应也正站在这一变革的风口浪尖。随着信息技术架构…

为什么越来越多的男性开始光顾美容机构?美业管理系统/个案疗愈系统源码

近年来&#xff0c;我们可以清晰地观察到一个明显的趋势&#xff1a;越来越多的男性开始光顾医美美容机构。这种现象的出现并非偶然&#xff0c;而是由多种因素共同作用的结果。 本文将结合社会观念的转变、媒体和广告的影响、职业发展压力、技术进步以及自我关注和健康意识的…

基于非线性干扰观测器的六自由度机械臂控制

1.观测器公式推导 当存在扰动时&#xff0c;机械臂的动力学方程如下&#xff1a; 对上式进行恒等变化得&#xff1a; 设计干扰观测器&#xff1a; 令&#xff0c;则&#xff1a; 观测误差满足 &#xff0c;取&#xff0c;因加速度不可测&#xff0c;定义辅助向量&#xff1a; …