【问题标题】:Destructor vs member function race again析构函数与成员函数再次竞争
【发布时间】:2014-06-08 01:55:08
【问题描述】:

我已经看到过类似的问题:Destructor vs member function race ..但没有找到以下答案。假设我们有一个拥有某个工作线程的类。类的析构函数如下所示:

~OurClass
{
    ask_the_thread_to_terminate;
    wait_for_the_thread_to_terminate;
    ....
    do_other_things;
}

问题是:我们是否可以在工作线程中调用 OurClass 的成员函数,因为我们确信所有这些调用都将在析构函数中的 do_other_things 之前完成?

【问题讨论】:

  • 谢谢大家的回答。我刚刚对 C++ 标准中的以下语句感到困惑:“一旦为对象调用析构函数,该对象就不再存在;”

标签: c++ multithreading


【解决方案1】:

是的,你可以。成员变量的破坏只会在do_other_things 完成执行后开始。在对象被破坏之前调用成员函数是安全的。

【讨论】:

    【解决方案2】:

    嗯,你可以这样做,但这样很容易出错。例如,如果您执行以下操作:

    ~OurClass
    {
        delete *memberPointer_; 
        ask_the_thread_to_terminate; // the thread calls OurClass::foo();
        wait_for_the_thread_to_terminate;
        ....
        do_other_things
    }
    
    void OurClass::foo()
    {
        memberPointer->doSomething();
    }
    

    你会有麻烦的。这也使通读代码变得更加困难。所以你必须小心操作的顺序和类似的东西。一般来说,如果可以改变架构来避免这种复杂的结构,我会建议这样做。

    【讨论】:

    • 这就是为什么正确资源处理很重要。析构函数中的delete 语句是一个典型的错误。改用智能指针,这样可以确保不会发生这样的错误。
    【解决方案3】:

    任何数据成员的隐式销毁发生在你的析构函数的最后一个显式行执行之后,所以所有这些数据成员在你等待线程时仍然可以正常工作。因此,您只能避免对任何数据成员进行任何过早的显式破坏(如 SingerOfTheFall 的病态代码所示)。

    【讨论】:

    • 我应该记住“病态密码”的表达方式,听起来很花哨;)
    猜你喜欢
    • 2010-10-02
    • 2018-02-02
    • 2019-03-09
    • 1970-01-01
    • 2015-05-14
    • 2016-01-29
    • 2021-11-19
    • 2015-06-13
    • 2018-05-13
    相关资源
    最近更新 更多