Ctrl-C对于C++ Win32控制台应用程序的影响是什么?

17
  1. 有没有办法以某种方式处理此事件?
  2. 在堆栈展开和静态/全局对象的释放方面会发生什么?
3个回答

13

在控制台应用程序中,按下Ctrl-C会生成一个信号。该信号的默认处理程序将调用ExitProcess函数来终止应用程序。你可以使用SetConsoleCtrlHandler函数为信号设置自己的处理程序,以覆盖这种行为。


1
静态变量的释放怎么处理? - Assaf Lavie

7

编辑:应该是SIGINT,而不是SIGTERM。Assaf报告称,在未处理的SIGINT情况下没有对象被销毁(至少在Windows上)。

系统发送一个SIGINT信号。这个概念适用于所有C实现(有些略有不同)。要处理它,您需要调用signal函数,并指定一个信号处理程序。请参阅Open GroupMSDN上关于signal函数的文档。

第二个问题比较棘手,可能取决于具体实现。最好的办法是处理信号,这样可以手动使用deleteexit()


谢谢。顺便提一下,您链接的MSDN页面表明系统发送SIGINT信号(而NT及以上根本不发送SIGTERM信号)。 - Assaf Lavie
此外,SIGINT 转换为 ExitProcess,不会触发任何对象(全局、本地静态、自动)的销毁。然而,如果将 sigint 转换为 exit(),则全局/静态对象将按初始化的相反顺序进行析构(但自动对象不会)。 - Assaf Lavie

4
您可以使用一些简单的代码来测试堆栈展开是否发生:
#include <iostream>
#include <windows.h>
using namespace std;

struct A {
    ~A() { cerr << "unwound" << endl; }
};

int main() {
    A a;
    while(1) {
        Sleep(1000);
    }
}

是否发生取决于实现方式,取决于运行时如何处理 Ctrl-C。根据我的经验,这种情况并不会发生。


我很难相信这样的测试,因为我永远不确定行为是否会因不同的项目配置(例如库、dll、本地、托管、多线程和其组合)而有所不同。因此,我宁愿得到“真正”的答案,而不是依赖于这样的测试。 - Assaf Lavie
没有“正确”的答案 - C++标准对此问题没有任何规定,因此您得到的结果将始终取决于实现。 - anon
VC的真正答案对我来说已经足够了。但是我怀疑答案可能因项目类型而异,就像我之前所说的那样。 - Assaf Lavie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接