COM`IStream`接口指针和来自不同线程的访问

时间:2013-11-11 09:24:53

标签: windows multithreading winapi com marshalling

对于任何 IStream实现是否是正式的COM要求,它应该是线程安全的,在通过相同的接口指针对IStream方法的并发访问方面跨线程?

我不是在讨论数据完整性(通常,读/写/搜索应该与锁同步)。问题是需要使用COM marshaller将IStream对象传递给来自不同COM公寓的线程。

这是一个比我提到的关于IStream as returned by CreateStreamOnHGlobal更普遍的问题,请参阅更多技术细节。我只是想更好地理解这些东西。

已编辑,我在MSDN上找到了此信息:

  

线程安全。 SHCreateMemStream创建的流是线程安全的   从Windows 8开始。在早期的系统上,流不是线程安全的。    CreateStreamOnHGlobal创建的流是线程安全的。

现在我相信,IStream返回的CreateStreamOnHGlobal对象是线程安全的,但是没有要求其他IStream实现应遵循此

1 个答案:

答案 0 :(得分:1)

不,不是。对另一个问题的公认答案是错误的。 Hans Passant的回答是正确的。你应该删除这个问题,因为它预先假定了一个错误,即CreateStreamOnHGlobal返回一个线程安全的IStream。它没有。然后,您会问其他IStream实现是否属实。它不是。

在计算机编程中,特别是COM,对象有保证他们给予并保证他们不给。如果您使用符合其保证的对象,那么它将一直有效(除了错误)。如果您超出保证范围,它可能在大多数情况下仍然有效,但不再保证。

通常在COM中,线程安全保证由其中一个标准线程模型给出。

见这里:http://msdn.microsoft.com/en-us/library/ms809971.aspx

  • 单元线程对象可以在多个线程上实例化,但只能在实例化的特定线程中使用。
  • 多线程单元对象可以在多线程单元中实例化,并且可以在任何这些线程中使用。
  • "两个" - 线程对象都可以在任何线程中实例化,并从任何线程中使用。

注意: 线程模型属于对象,不属于接口。支持IStream的某些对象可能是单线程的,其他对象可能是完全线程安全的。这取决于实现接口的代码。因为接口只是规范,并且线程安全不是它所涵盖的内容。

编组界面总是无害的。如果线程的线程模型与对象的主线程兼容,则将获得完全相同的接口指针。如果它们不兼容,您将获得代理。但是,对于编组从来没有伤害过,除非你知道对象是兼容的,否则你应该总是编组。

然而,实施者始终可以提供额外的保证。

对于CoMarshalInterthreadInterfaceInStream,在文档中告诉您,使用IStream可以使用返回的CoUnmarshalInterfaceAndReleaseStream接口在目标线程上进行解组。

也就是说,您已获得额外保证。所以你可以依靠这种工作。

但这在任何时候都不适用于IStream的任何其他实例。

所以你应该总是封杀他们。