c++ - IUnknown.Release 标准实现竞争条件?

标签 c++ windows multithreading winapi com

这是实现 IUnknown COMRelease 方法的标准(不是推荐)方法界面(直接取自MSDN):

ULONG CMyMAPIObject::Release()
{
    // Decrement the object's internal counter.
    ULONG ulRefCount = InterlockedDecrement(m_cRef);
    if (0 == m_cRef)
    {
        delete this;
    }
    return ulRefCount;
}

我想知道如果公寓模型不是 STA 是否会出现竞争条件:

  • 说还剩一个引用
  • 线程 1 通过调用 Release 释放它
  • 它在 delete this 之前运行并停止
  • 线程 2 被调度并获取对象的新引用,例如通过调用 QueryInterfaceAddRef
  • 线程1继续执行并运行delete this
  • 线程 2 留下了一个无效的对象

对我来说,确保一致性的唯一方法是创建一个标志,比如 deleted,锁定整个关键部分,即除了返回之外的所有 Release 方法,并将标志设置为 true

并且在 AddRefQueryInterface 方法中检查这个标志,如果它被设置则拒绝新引用的请求。

我错过了什么?

提前致谢。

最佳答案

thread 2 is scheduled and obtain a new reference to the object, e.g. by calling QueryInterface or AddRef

只有当它已经引用了 IUnknown 或该对象实现的其他接口(interface)之一时,它才能执行此操作。之前为其调用了 AddRef()。因此,引用计数永远不会被另一个线程的 Release 调用减少到小于 1 的值。

请正确编写代码,您必须将 ulRefCount 与 0 进行比较,而不是 m_cRef。

关于c++ - IUnknown.Release 标准实现竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19142613/

相关文章:

c# - ThreadPool 挫折 - 线程创建超过 SetMaxThreads

java - 如何在 eclipse rcp 中显示作业进度?

php - 如何从 C++ 调用 php-cgi

windows - 用于列出文件夹中的文件并将其导出到文本文档的脚本

Windows 批处理循环遍历子文件夹并运行命令

iphone - 有什么已知的方法可以通过 USB 数据线(无 wifi)从 iPhone 浏览 PC localhost?

java - Transaction java 中的 BlockingQueue

c++ - 类模板和友元中的运算符重载

c++ - 为什么 C++ 中的多重定义错误不是由 const int 声明引起的?

c++ - 运算符 << 作为成员函数