测试对象是否未删除

Testing if object is not deleted

本文关键字:删除 是否 对象 测试      更新时间:2023-10-16

我的对象创建了一个线程,该线程在对象创建者的生命周期中修改对象创建者。问题是,线程在被破坏时不应该调用对象方法。我已经找到了解决这个问题的办法,我想知道它是否是最好的办法。

class A
{
    shared_ptr<int> guard = make_shared<int>(0);
public:
    weak_ptr<int> getGuard() { return guard; }
    void method() {}
    A()
    {
        thread([this]
        {
            const auto &guard = getGuard();
            while(!guard.expired()) 
                method();
        });
    }
};

while循环不是一种线程安全的方法,可以确保只有在guard指向的对象仍然存在时才调用method。原因是在对expired的调用和对method的调用之间,另一个线程可能会导致对象的破坏。

执行此检查的安全方法是尝试将弱指针提升为共享指针:

while (true)
{
    shared_ptr<int> sp = getGuard().lock();
    if (sp)
    {
        method();
    }
    else
    {
        return;
    }
}

通过将弱指针提升为共享指针,调用代码在对method的调用期间参与对象的所有权,确保在调用代码使用它时它不会被破坏。

您也未能连接或分离线程。从您的示例来看,您似乎想要分离它,以便A的构造函数可以在线程完成执行之前退出。在这种情况下,您的代码应该是这样的:

thread([this]
{
    ...
}).detach();

如果您想确保对象在调用method时不会被销毁,但在其他时候可以被销毁,那么您需要在对象本身保留一个weak_ptr,并在调用方法时锁定它。类似于:

class A : std::enable_shared_from_this<A>
{
public:
    void method() {}
    A()
    {
        std::weak_ptr<A> self(shared_from_this());
        thread([=self]
        {
            while (auto This = self.lock())
                This->method();
        }).detach();
    }
};

这个对象现在只能通过make_shared创建——尝试以任何其他方式创建都会导致未定义的行为,并且可能会崩溃。