我有一个 native Visual C++ NT 服务。当服务启动时,它的线程调用 CoInitialize()
将线程附加到 STA - 服务线程通过 COM 接口(interface)使用 MSXML。
当服务收到 SERVICE_CONTROL_STOP
时,它会在消息队列中发布一条消息,然后检索该消息并调用 OnStop()
处理程序。处理程序清理内容并调用 CoUnitialize()
。大多数时候它工作正常,但偶尔会挂起后一个电话。我无法稳定地重现此行为。
我用谷歌搜索了一段时间,发现了以下可能的解释:
- 未能释放拥有的所有 COM 对象
- repeatedly calling
CoInitializeEx()
/CoUnitialize()
for attaching to MTA - failing to dispatch messaged in STA threads
第一个不太可能——使用 MSXML 的代码经过了很好的测试和分析,它使用智能指针来控制对象的生命周期,所以泄漏对象的可能性很小。
第二个看起来不太可能是原因。我附加到 STA 并且不重复调用这些函数。
第三个看起来或多或少有可能。当线程正在处理消息时,它不再运行消息循环——它已经在循环中了。我想这可能是原因。
后者是否可能是导致此问题的原因?我还应该考虑哪些其他原因?如何轻松解决此问题?
最佳答案
不要在处理 SCM 消息的线程中做任何有影响的事情,它处于一个奇怪的魔法上下文中 - 您必须尽快响应 SCM 的请求而不采取任何阻塞操作。通过 STOP_PENDING 告诉它你需要额外的时间,排队另一个线程来做真正的清理,然后立即完成 SCM 消息。
至于 CoUninitialize,只需附加 WinDbg 并转储所有线程 - 死锁很容易诊断(也许无法修复!),您已经在堆栈中找到了所有犯罪方。
关于windows - 如何解决卡在 CoUnitialize() 上的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3820971/