【问题标题】:Destructor vs member function race析构函数与成员函数竞赛
【发布时间】:2010-10-02 11:55:11
【问题描述】:

当我在析构函数中时,是否有其他线程会开始执行对象的成员函数?这种情况该如何处理?

【问题讨论】:

    标签: c++ multithreading destructor


    【解决方案1】:

    C++ 对在对象被删除后使用它没有内在的保护 - 忘记竞争条件 - 另一个线程可以在你的对象被完全删除后使用它。

    要么:

    1. 确保只有一个位置 代码拥有该对象,它是 无人时负责删除 正在使用该对象。
    2. 制作 对象引用计数 - 添加 显式引用计数代码,或 找到合适的基类 实现引用计数

    【讨论】:

    • 一个很好的提示是使用boost::shared_ptr<> 进行引用计数。它还支持 weak_ptr<>enable_shared_from_this 之类的结构,这使得生命周期管理的一些好的部分变得非常容易。
    • 不幸的是,遵循任一建议都不足以避免潜在的数据竞争。想象一下:线程 A 创建对象并将引用传递给线程 B。在 B 上,调用了一个变异成员函数。之后,A 销毁需要访问成员变量的对象。
    【解决方案2】:

    你不应该破坏一个对象,除非你确定没有其他东西会尝试使用它——理想情况下没有其他东西可以引用它。当您调用 delete 时,您需要更仔细地查看。

    【讨论】:

    • 完美、简单的答案。更进一步,这不仅会发生在析构函数内部,也可能发生在你离开析构函数之后。语言无法修复糟糕的设计。
    • 谢谢。但是,我应该建议道格拉斯·利德的答案比我的更完整。
    【解决方案3】:

    如果您因为异常处理程序中的堆栈展开而处于析构函数中,我建议您重新排列代码,以便在序列化块中捕获异常。

    在块之后,您检查对象是否仍然有效并调用您的方法。这样一个线程中的异常,将允许其他线程优雅地处理对析构函数的调用。

    【讨论】:

    • 如果您的对象被多个线程共享,那么异常不应触发其销毁。
    猜你喜欢
    • 2014-06-08
    • 1970-01-01
    • 2019-03-09
    • 2015-05-14
    • 2016-01-29
    • 2021-11-19
    • 2015-06-13
    • 2018-05-13
    • 2011-01-16
    相关资源
    最近更新 更多