【问题标题】:Is CoInitialize(NULL) call expensive after CoInitializeEx(NULL, COINIT_MULTITHREADED) on the same thread?在同一线程上 CoInitializeEx(NULL, COINIT_MULTITHREADED) 之后调用 CoInitialize(NULL) 是否昂贵?
【发布时间】:2017-07-14 02:51:21
【问题描述】:

我的代码在一个线程上调用CoInitializeEx(NULL, COINIT_MULTITHREADED),然后在同一个线程上调用CoInitialize(NULL)

我知道CoInitialize(NULL) 调用会以RPC_E_CHANGED_MODE 失败,但这不是我关心的问题。这个错误由​​代码正确处理如下:-

if (retValue == RPC_E_CHANGED_MODE) {
    thModel = kThModelMulti;  // thread was initialized with MTA model
}

请不要担心功能方面。 调用CoInitialize(NULL) 是否存在性能问题 - 这会很贵吗?如果是这样,我将更改代码以找出如果 CoInitializeEx 已经被调用,甚至不调用CoInitialize(NULL)

【问题讨论】:

  • @Dan,感谢编辑。
  • 它总是会失败。迅速地。随机调用这样一个非常重要的函数是一个非常糟糕的主意。你所担心的是它会成功。你没有兑现你做出的承诺。
  • 请不要将您的问题更改为与发布答案时的实时问题完全不一样的内容。此外,我们不知道“昂贵”对您来说是什么,或者为什么您调用一个可能会失败的函数,当您显然可以提前确定时,它会失败。
  • 代码中有一些限制,因此您无法提前知道。对于“昂贵”,我的意思是所花费的时间相当于 CoInitializeEx(在这种情况下)。
  • 我了解您想要做什么,但您正在尝试解决症状,而不是真正的问题。 COM 无法询问是否已调用 CoInitialize,因为您不需要知道。调用 CoInitialize 的代码必须拥有线程。如果一段代码不知道是否/哪个 CoInitialize 已经被调用,则该代码不变不拥有线程并且没有调用 CoInitialize 的业务。每次我看到这样的代码时,都会有一个潜在的破坏架构。思考更高的层次,和/或请发布您实际在做什么。

标签: c++ multithreading com


【解决方案1】:

调用CoInitialize(NULL) 与调用CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) 的效果相同。如果您在已经调用CoInitializeEx(NULL, COINIT_MULTITHREADED) 的线程上调用CoInitialize(NULL),它将失败并返回错误代码RPC_E_CHANGED_MODE。这在documentation 中特别指出:

线程的并发模型设置后,无法更改。在以前初始化为多线程的单元上调用 CoInitialize 将失败并返回 RPC_E_CHANGED_MODE。

性能影响无关紧要。这是一个功能问题,也就是错误。

【讨论】:

  • 我编辑了我的问题以解决您所说的问题。谢谢!
  • @RakeshAgarwal:如果您的代码调用CoInitialize(NULL),它会这样做,因为调用线程实现了特定于 STA 的同步。无法正确处理失败的情况,因为调用线程已经在 MTA 中。
  • 在代码的这个地方,它想知道线程模型,但不知道是否已经调用了CoInitializeEx(...)。因此,它调用CoInitialize(NULL) 并根据返回值了解线程模型。
  • @RakeshAgarwal:调用CoInitialize(NULL) 无法验证之前是否调用过CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)。如果您打算改为写COINIT_MULTITHREADED,那仍然是个坏主意:将状态更改为查询状态的一种方式。如果您需要自己跟踪线程状态,并且不知道在哪里存储这些数据,请改用TLS
猜你喜欢
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 2012-03-23
  • 1970-01-01
  • 2017-12-08
  • 2015-01-31
  • 2015-06-05
相关资源
最近更新 更多