【问题标题】:Proper destruction of object in a multi threaded environment在多线程环境中正确销毁对象
【发布时间】:2018-12-08 01:33:48
【问题描述】:

我继承了我认为没有正确销毁对象的多线程遗留代码。

class A
{
private:
    TCCState *b; // TCCState is struct from third party library
public:
    static A func1();
    ~A();
};

std::unique_ptr<A> A::func1()
{
    std::unique_ptr<A> res(new A());
    int ret = gen_tcc_context(res); // gen_tcc_context is library function
    return res; // this res is used as std::unique_ptr<A> temp(std::move(A::func1())); and then properly destroyed 
}

A::~A()
{
    if (b != nullptr){// Is this necessary? If yes, should I used a lock_guard for this code? 
        tcc_delete(b);// tcc_delete is a library function. This raises an exception - Assertion failed: ("Invalid file descriptor. File possibly closed by a different thread",0)
    }
}

看起来析构函数中的代码片段试图关闭已经关闭的东西。析构函数中的代码片段真的有必要吗?如果是,使用 lock-guard 安全吗?

【问题讨论】:

  • 在实际代码中,类是否遵循the rules of three, five or zero
  • 这段代码无法编译,因为func1() 在类声明中被声明为返回A 对象,但在其定义中被声明为返回std::unique_ptr&lt;A&gt;
  • 我在这段代码中看不到任何不能正确释放东西的东西。只分配了 1 个A 对象,并且只被销毁一次,并且在被销毁时删除了它的 tcc 资源。 A 对象在几个 unique_ptr 对象周围移动的事实并没有改变这一点。 A 对象在最终的unique_ptr 被破坏之前不会被破坏。但是,这与多线程有什么关系?此代码中没有线程。
  • 如果您定义自己的删除器,您可以将TCCState 放入std::unique_ptr&lt;TCCState, TCCStateDeleter&gt;

标签: c++ c++11 destructor


【解决方案1】:

当对象准备好被销毁时,这意味着只有当前线程正在使用它。如果这不是真的,那么对象的生命周期管理是无效的。所以底线析构函数不需要同步。

题外话:
如果正确定义指针,则根本不需要析构函数:

class TCCState_deleter {
public:
    void operator()(TCCState *b) {
         tcc_delete(b);
    }
};

class A
{
private:
    std::unique_ptr<TCCState, TCCState_deleter> b;
public:
    static A func1();
};

【讨论】:

    猜你喜欢
    • 2020-11-07
    • 2014-10-11
    • 2018-03-31
    • 2015-01-10
    • 2012-11-30
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多