【问题标题】:How to do async destruction of object and immediately assign a new one如何对对象进行异步销毁并立即分配一个新对象
【发布时间】:2019-12-30 09:37:25
【问题描述】:
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();

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

但是,还是有问题。

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

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

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

【问题讨论】:

  • 为什么不保留线程,并在创建新的A 时为它们分配新的工作?
  • a = A(); 不会删除对象;它摧毁它。两者有很大的不同。

标签: c++ multithreading


【解决方案1】:

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

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

移动分配确实只有在第一个实例被销毁时才会完成。

所以除非你想继续下一个代码,前提是 sn-p 是正确的。

否则swap 可能是延迟销毁第一个实例的解决方案。

【讨论】:

  • 你的意思是A a = A(); A b = A(); std::swap(a,b); 那么我根本就不关心b 了?将来它仍然必须被破坏,它会阻止我正在做的任何事情,不是吗?
  • @GuerlandoOCs:是的,您延迟 b 在范围结束时销毁,而不是分配。您可能会在swap 之前向b 发出信号以停止
  • 但是有没有办法异步销毁b,这样我就不必等待我的线程停止了?
  • 你可以detach他们而不是join,但你必须保证他们在申请前完成。
  • 我无法分离它们,因为它们所做的工作是在 A 本身上,所以如果 A 被破坏,它们会导致程序崩溃
猜你喜欢
  • 1970-01-01
  • 2017-06-29
  • 2012-02-06
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2012-05-02
相关资源
最近更新 更多