【问题标题】:Windows console application - signal for closing eventWindows 控制台应用程序 - 关闭事件的信号
【发布时间】:2014-12-26 19:56:54
【问题描述】:

在 Windows 控制台应用程序中,可以使用以下命令捕获按下 ctrl+c

#include <stdio.h>
#include <signal.h>

void SigInt_Handler(int n_signal)
{
    printf("interrupted\n");
}

int main(int n_arg_num, const char **p_arg_list)
{
    signal(SIGINT, &SigInt_Handler);
    getchar(); // wait for user intervention
}

这很好用,但如果用户按下关闭控制台窗口的十字×,它根本不起作用。有什么信号吗?

我需要这个的原因是我有这个 CUDA 应用程序,如果在计算某些东西时关闭,它往往会导致计算机崩溃。代码是多平台的,所以我更喜欢使用信号而不是SetConsoleCtrlHandler。有什么办法吗?

【问题讨论】:

    标签: c signals console-application windows-console


    【解决方案1】:

    正确的是SIGBREAK,你可以试试:

    #include <stdio.h>
    #include <signal.h>
    
    void SigInt_Handler(int n_signal)
    {
        printf("interrupted\n");
        exit(1);
    }
    
    void SigBreak_Handler(int n_signal)
    {
        printf("closed\n");
        exit(2);
    }
    
    int main(int n_arg_num, const char **p_arg_list)
    {
        signal(SIGINT, &SigInt_Handler);
        signal(SIGBREAK, &SigBreak_Handler);
        getchar(); // wait for user intervention
        return 0;
    }
    

    关闭控制台窗口后,程序将打印"closed",并返回2。

    【讨论】:

    • 难道不是你不能在那个时候中止退出吗?现在似乎可以防止控制台在处理程序内退出。
    • 我猜你可以永远等待,然后会弹出一个“强制关闭”对话框。但由于没有返回值,我猜你不能中止。我只是想要一种方法来延迟退出并正确关闭应用程序。
    • @theswine,在 Vista 及更高版本中没有对话框。如果控制处理程序返回TRUE 或返回时间超过5 秒,Windows (csrss.exe) 将强制终止进程。如果处理程序返回FALSE,则默认处理程序调用ExitProcess。在这些情况下,进程退出代码为STATUS_CONTROL_C_EXIT (0xC000013A)。
    • 在 Windows 10 中这不再起作用,使用SIGBREAK 安装的信号处理程序永远不会被调用,并且应用程序会立即退出。
    • @Youda008,不,SIGBREAK 处理程序在 Windows 10 中为 CTRL_BREAK_EVENTCTRL_CLOSE_EVENT 调用,即使在 Windows 终端下也是如此。唯一有点不稳定的情况是控制台的CTRL_LOGOFF_EVENTCTRL_SHUTDOWN_EVENT。它们被发送并映射到SIGBREAK,用于一个简单的控制台应用程序。但是,如果进程加载 user32.dll(即,如果进程附加到窗口站和桌面),则不会发送它们。预计连接到桌面会话的应用将创建一个窗口并处理WM_QUERYENDSESSIONWM_ENDSESSION
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多