windows - 如何解决卡在 CoUnitialize() 上的进程?

标签 windows visual-c++ winapi com windows-services

我有一个 native Visual C++ NT 服务。当服务启动时,它的线程调用 CoInitialize() 将线程附加到 STA - 服务线程通过 COM 接口(interface)使用 MSXML。

当服务收到 SERVICE_CONTROL_STOP 时,它会在消息队列中发布一条消息,然后检索该消息并调用 OnStop() 处理程序。处理程序清理内容并调用 CoUnitialize()。大多数时候它工作正常,但偶尔会挂起后一个电话。我无法稳定地重现此行为。

我用谷歌搜索了一段时间,发现了以下可能的解释:

  1. 未能释放拥有的所有 COM 对象
  2. repeatedly calling CoInitializeEx()/CoUnitialize() for attaching to MTA
  3. 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/

相关文章:

windows - Windows 7之前的计时器合并

c++ - 使用 if(true) 子句缩小资源管理器对象的范围?

c++ - 如何将光标移动到 C++ 中最后打开的窗口(可能是弹出窗口)

c++ - 从 ".exe"+ 偏移量读取内存?

.net - 关于 WPF 中的 3D 效果

调用指令时 C++ 程序崩溃(C0000005 访问冲突)

c++ - 为什么 checked_array_iterator 在 VS2013 中不包含 <iterator> 就可以工作,但在 VS2017 中却失败了?

windows - 为什么 for/f 不忽略空行?

windows - 尝试使用 PowerShell 2.0 将 regfile 复制到另一个文件夹

windows - DLL是在内核态还是用户态加载的?