首页 > 解决方案 > 如何对对象进行异步销毁并立即分配一个新对象

问题描述

class A {
    A() {
    //initiate t1 and t2 here and put work for them to do
    }
    std::unique_ptr<std::thread> t1;
    std::unique_ptr<std::thread> t2;
}

现在假设我执行以下操作:

A a = A();
a = A();

在第一行中,a将是一个A包含一些正在运行的线程的对象。当第二行运行时,它会删除旧A对象以创建新对象。此删除不尊重正在运行的线程。

现在,假设我进行以下修改:

class A {
    A() {
    //initiate t1 and t2 here and put work for them to do
    }
    ~A() {
    //send signal to t1 for it to stop 
    //send signal to t2 for it to stop
    //wait for threads to stop
        t1.join();
        t2.join(); 
    }
    std::unique_ptr<std::thread> t1;
    std::unique_ptr<std::thread> t2;
}

这样,当我跑步时

A a = A();
a = A();

线程将在它们的指针之前优雅地停止t1并被t2破坏,因为类的析构函数在其成员的析构函数之前被调用。

但是,仍然存在问题。

执行第一行时,会创建A a = A();一个A类并开始运行线程。当第二行到达时a = A();,我认为调用了析构函数,a我们必须等待所有线程都被销毁(这可能需要时间),然后才A分配一个新的。这不好,因为我们的代码被阻塞,直到所有线程都完成,然后才A分配一个新的。

那么,有没有办法以异步方式破坏对象并立即分配一个新对象?

我考虑过使用 std::async 调用析构函数,但我发现我不应该手动调用析构函数,因为它们的第二次调用(当对象超出范围时)将具有未定义的行为。

标签: c++multithreading

解决方案


我认为 a 的析构函数被调用,我们必须等待所有线程被破坏(这可能需要时间),然后才分配一个新的 A 。

是的,但是新的临时文件A已经存在,因此在构造函数中开始的工作将会进行。

只有在第一个实例被销毁后,移动分配才会真正完成。

因此,除非您想继续下一个代码,否则提供的代码段是正确的。

否则swap可能是延迟销毁一审的解决方案。


推荐阅读