千家信息网

vc控制台程序关闭事件时的处理方式是什么

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,本篇内容介绍了"vc控制台程序关闭事件时的处理方式是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成
千家信息网最后更新 2024年09月22日vc控制台程序关闭事件时的处理方式是什么

本篇内容介绍了"vc控制台程序关闭事件时的处理方式是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

关键控制台API函数:SetConsoleCtrlHandler

在支持C++ 11以上的编译器中,你可以这么做。

SetConsoleCtrlHandler([](DWORD fdwctrltype)->BOOL {    if (fdwctrltype == CTRL_CLOSE_EVENT) {        // 你的善后代码...        return TRUE;    }    return FALSE;}, TRUE);

最初这么做是很舒服的,但之后发现了问题:

Windows控制台在标记状态下,printf之类的输出函数,会阻塞在标记选择时(点控制台左上角-编辑-标记)。

这就导致了,我们的善后代码中,可能会死锁,例如你要优雅的结束一个线程,这个线程在最后的时候printf了。

线程里printf等待标记状态,SetConsoleCtrlHandler回调函数里等待线程结束,总之就是死锁。

我本来想着,去找到能够获取这种标记状态的控制台API,但找了很久都没有结果。

最后,我就考虑,有没有方法让printf不与标记状态发生死锁,答案是: 输出流重定向。

所以,代码变成这样:

SetConsoleCtrlHandler([](DWORD fdwctrltype)->BOOL {    if (fdwctrltype == CTRL_CLOSE_EVENT) {        char szbuf[0x1000];        setvbuf(stdout, szbuf, _IOFBF, 0x1000);        // 你的善后代码...        return TRUE;    }    return FALSE;}, TRUE);

这么做之后,世界果然更美好了,如果最后这些日志信息对你来说是重要的,那么你可能需要写更多代码去实现。

知识点扩展:

实例:

BOOL WINAPI ConsoleHandler(DWORD CEvent){DWORD e = 0;switch (CEvent){case CTRL_C_EVENT:e = CTRL_C_EVENT;break;case CTRL_BREAK_EVENT:e = CTRL_BREAK_EVENT;break;case CTRL_CLOSE_EVENT:e = CTRL_CLOSE_EVENT;break;case CTRL_LOGOFF_EVENT:break;case CTRL_SHUTDOWN_EVENT:break;}return true;}int main(int argc, char* argv[]){if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE){//安装失败return -1;}GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); //手工产生一事件}

"vc控制台程序关闭事件时的处理方式是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0