避免弱引用的建议并不能解决竞争问题。
T1 operator new, create object, references: 1
T1 passes interface object reference to T2, thinking it can "share" ownership
T1 suspends
T2 resumes
T2 QueryInterface
T2 suspends before InterlockedIncrement, references: 1
T1 resumes
T1 Calls Release
T1 suspends between InterlockedDecrement and operator delete, references: 0
T2 resumes, InterlockedIncrement occurs, references 1
T2 suspends
T1 resumes, operator delete executes, references 1 !!!
T1 suspends
T2 resumes
T2 Any reference to the interface is now invalid since it has been deleted with reference count 1.
这可以在 COM 服务器中解决。然而,COM 客户端不应依赖于阻止这种竞争条件的服务器。因此,COM 客户端不能在线程之间共享接口对象。唯一应该被允许访问接口对象的线程是当前“拥有”接口对象的一个线程。
T1 不应该调用 Release。是的,它可以在将接口对象传递给 T2 之前调用 AddRef。但这可能无法解决比赛,只能将其移至其他地方。最佳实践是始终保持一个接口对象、一个所有者的概念。
如果 COM 服务器希望支持两个(或更多)接口可以引用某些共享的服务器内部状态的概念,则 COM 服务器应通过提供 CreateCopyOfInstance 方法来通告合同并在内部管理争用。当然,也有处理这种“扇出”的服务器示例。看看微软的持久存储接口。在那里,接口不会“扇出”..每个接口都应该由单个用户(线程/进程/任何东西)拥有,并且“扇出”在内部由服务器管理,并提供给COM 客户端控制争用问题的某些方面。因此,Microsoft 的 COM 服务器必须将竞争条件作为其与客户的合同的一部分。