终于搞出了能优雅退出的程序
今天是星期日。昨晚是后半夜5点钟睡的。刚才上午9点多钟就醒了,想解决问题,所以睡不消停。就起来继续研究。
前几天一直能在子对话框中成功使用WaitForSingleObject来等待线程结束,但昨天在D3主界面中用同样方法就失败了。这个界面中有8个线程,我机器中可能有某种病毒,所以经常会导致90%以上的CPU使用率,所以这8个线程想要全部停止,有时需要等待8秒钟时间。而我以前根本就没有等待,直接就OnDestroy了。所以关闭程序的时候,8个线程都是活的,会产生程序崩溃界面。
有时我经常觉得,自己电脑中的的那种占用CPU的病毒实质是“神助攻”,或者是VS编译器的商家等暗中设套来帮我。因为它有时候有,有时候没有。一旦有了,就能帮我模拟极端用户条件下的运行情况,这样就可以设置对策了。
WaitForSingleObject在主进程界面中无法使用,因为它是阻塞性的,影响消息流动,导致界面卡死,分析见: https://blog.51cto.com/thgenius/1384558
(但有时并不卡死,所以它很迷惑人)。所以出路就是使用MsgWaitForMultipleObjects,而微软并未提供该函数的具体用法,所以只能猜谜。我查看网上多数都是拆开单独用了,比如像这样:
MsgWaitForMultipleObjects(1, handles, FALSE, INFINITE, QS_ALLINPUT)//注意其中的1
例子见:
https://stackoverflow.com/questions/1461378/understanding-msgwaitformultipleobjects
https://www.cnblogs.com/ling123/p/8653580.html
https://blog.csdn.net/what951006/article/details/75353060
我按他们的办法来逐个关闭线程,很费事,昨晚弄到后半夜5点钟,还是不成功。后来在“灰信网”上找到了一个看似非常好的代码(WaitForThreadExit): https://www.freesion.com/article/90421065876/
今天从上午9点钟后就在研究使用这个代码,但还是不行!然后我找到了一个说行的帖子: http://blog.chinaunix.net/uid-28765492-id-3713597.html
按照这个线索,我就想到“莫非MsgWaitForMultipleObjects只能检测自定义事件,而无法像WaitForSingleObject那样检测到线程结束事件?”
带着这样的疑问,我就在线程结束位置使用了SetEvent,然后给MsgWaitForMultipleObjects传递事件句柄,结果就大获全胜了。
========================
然后我发现,在极端条件下的结束等待中,用户会不耐烦地反复尝试关闭程序,但这种操作竟然会造成程序死锁。我用一个ShowWindow(false)就解决了。这样一来,表面看来程序立马就关闭了,但你在任务管理器中看看,你的进程其实还在那里,在等待线程结束呢。时间一到(0~8秒),就从任务队列中彻底消失了。这才符合Windows程序的一般规律啊。