【问题标题】:What exactly is the effect of Ctrl-C on C++ Win32 console applications?Ctrl-C 对 C++ Win32 控制台应用程序的影响到底是什么?
【发布时间】:2010-10-29 05:08:54
【问题描述】:
  1. 能否以某种方式处理此事件?
  2. 在堆栈展开和释放静态/全局对象方面会发生什么?

【问题讨论】:

    标签: c++ winapi console copy-paste


    【解决方案1】:

    控制台应用程序中的 Ctrl-C 将生成一个信号。此信号的默认处理程序调用 ExitProcess 来终止应用程序。您可以通过使用SetConsoleCtrlHandler 函数为信号设置自己的处理函数来覆盖此行为。

    【讨论】:

    • 释放静态变量怎么样?
    【解决方案2】:

    编辑:SIGINT,而不是 SIGTERM。 Assaf 报告说,没有任何对象因未经处理的 SIGINT 而被破坏(至少在 Windows 上)。

    系统发送一个 SIGINT。这个概念适用于所有 C 实现(有一些差异)。为了处理它,你调用信号,指定一个信号处理程序。请参阅Open GroupMSDN 上有关信号功能的文档。

    第二个问题有点棘手,可能取决于实现。最好的办法是处理信号,它允许您手动使用deleteexit()

    【讨论】:

    • 谢谢。仅供参考,您链接到的 MSDN 页面建议系统发送 SIGINT(并且 NT 向上根本不发送 SIGTERM)。
    • 此外,转换为 ExitProcess 的 SIGINT 不会触发任何类型的对象(全局、本地静态、自动)的销毁。如果,otoh,您将 sigint 转换为 exit(),全局变量/静态变量将以初始化的相反顺序成为析构函数(但自动不是)。
    【解决方案3】:

    您可以通过一些简单的代码测试是否发生堆栈展开:

    #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、本机、托管、多线程及其组合)的行为是否会有所不同)。所以我宁愿得到“真实”的答案,而不是自己依赖这样的测试。
    • 没有一个“真实”的答案——C++ 标准在这个问题上没有什么可说的,所以你得到的总是依赖于实现。
    • 嗯,VC的真实答案对我来说已经足够了。但正如我所说,我怀疑不同项目类型的答案可能会有所不同。
    猜你喜欢
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2016-11-16
    • 2010-11-04
    相关资源
    最近更新 更多