简体   繁体   English

关闭控制台窗口时优雅退出

[英]Graceful exit when closing console window

I'm trying to make a graceful exit from a console app when the close button is hit. 当关闭按钮时,我正试图从控制台应用程序中正常退出。

bool done = false;

BOOL ctrl_handler(DWORD event)
{
    if (event == CTRL_CLOSE_EVENT) {
        done = true;
        return TRUE;
    }
    return FALSE;
}

int main()
{
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);

    while (!done)
        do_stuff();

    cleanup();
    cout << "bye";
}

My handler gets called properly but the main thread does not resume afterwards so the "bye" never happens. 我的处理程序被正确调用,但主线程之后没有恢复,所以“再见”永远不会发生。 If I trap CTRL_C_EVENT instead and hit ^C in the console then the main thread is allowed to continue and exits gracefully. 如果我改为捕获CTRL_C_EVENT并在控制台中点击^ C,则允许主线程继续并正常退出。 Is there some way to allow the main thread to exit gracefully on console close? 有没有办法让主线程在控制台关闭时正常退出?

I've also tried using std::signal but it's the same. 我也尝试过使用std :: signal,但它是一样的。 Works for ^C but not for window close. 适用于^ C但不适用于窗口关闭。

Thanks Jonathan for the tip. 谢谢乔纳森的小费。

I saw that the handler is called on it's own thread. 我看到处理程序是在它自己的线程上调用的。 If the handler returns then the whole process is forced to exit so we need to give the main thread time to exit on its own. 如果处理程序返回,则整个进程被强制退出,因此我们需要给主线程时间自行退出。

bool done = false;

BOOL ctrl_handler(DWORD event)
{
    if (event == CTRL_CLOSE_EVENT) {
        done = true;
        Sleep(20000); // force exit after 20 seconds
        return TRUE;
    }
    return FALSE;
}

int main()
{
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);

    while (!done)
        do_stuff();

    cleanup();
    cout << "bye";
}

I think the better way would be to use: 我认为更好的方法是使用:

if (event == CTRL_CLOSE_EVENT)
{
    ExitThread(0);
//  return TRUE; // warning C4702: unreachable code
}

The ExitThread will terminate the thread from which ctrl_handler gets called. ExitThread将终止调用ctrl_handler的线程。 This way ExitProcess will not be called, and your main thread will be able to perform all the needed cleanup. 这样就不会调用ExitProcess ,你的主线程将能够执行所有需要的清理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM