我有一个COM / ATL dll,它在DllGetClassObject入口点初始化我的自定义记录器,并在覆盖ExitInstance函数中取消初始化此记录器。 Logger实现为单独的线程,定期检查其缓冲区并快速记录所有记录。
现在,问题。如您所知,Windows会定期检查未使用的COM dll并将其卸载。我想在dll卸载过程中等待记录器线程完成,但我无法找到正确的方法。我尝试了几种解决方案:
使用WaitForSingleObject等待记录器线程完成。这不起作用,因为主线程在DllMain函数内。
创建自定义事件并在记录器线程退出之前立即触发:
SetEvent(_loggerExitEvent);
// can be blocked here!
return 0;
这不起作用,因为此代码块不是原子的。记录器线程可以触发事件并被阻塞,直到从内存中卸载dll然后再次唤醒只会产生令人讨厌的访问冲突错误。
如果我100%确定记录器线程将返回,则在收到上述事件后使用TeminateThread。这非常不可思议。
循环我的主线程以定期检查记录器线程状态:
while(TRUE == ::GetExitCodeThread(_loggerThread, &loggerThreadExitCode) && loggerThreadExitCode== STILL_ACTIVE)
{
Sleep(100);
}
非常肮脏和不稳定。如果GetExitCodeThread返回FALSE怎么办?
所以,问题是,在dll卸载过程中有没有正确的方法等待另一个线程完成?或者我做错了什么?