【问题标题】:How to manage lifetime of the type "shortest of"?如何管理“最短”类型的生命周期?
【发布时间】:2016-10-31 18:00:03
【问题描述】:

当一个对象只有一个父对象时,我们使用组合,它应该关心对象的生命周期。我们在相同情况下使用unique_ptr,但对象可以是nullptr

当多个外部实体可能需要我们的对象时,我们使用shared_ptr,因此它的生命周期会延长,直到最后一个外部实体失去兴趣。

在这里,我想问另一个人生的情况。 如果对象需要最短几个持续时间怎么办?

这是一个例子。让我们有一个一次性计时器,它存储一个函子并在计数完成后执行它。这对我来说很有意义*,这个计时器对象在以下情况下被销毁:

1. fulfilling its task - therefore it should be able to destroy istelf

 or

2. the parent loosing interest in the timer - so the parent should be able to 
     destroy the object as well

目前,我使用了一个带有唯一指针的笨拙实现。这个问题的一个好的模式/指南/实现是什么?

* 原因:1) 仿函数可能拥有一些其他资源 2)定时器可能已经设置为一个非常大的数字,然后放弃 3)如果父级已经被销毁,我们一般不想调用它的回调

【问题讨论】:

  • 这与线程取消有很多共同点,当你计算一些东西以响应网络请求时,连接被突然终止。完成计算不会导致任何损坏,但会浪费资源。

标签: c++ c++11 object-lifetime


【解决方案1】:

这里存在严重的并发和重入问题。

当两段或多段代码有权删除一个指针时,任何一段代码都不能可靠地取消引用该指针,因为这样做时另一段可能会破坏它。

类似地,在任何其他非本地(例如函数调用)运行时,您检查是否拥有所有权的任何分支都可能变得陈旧,即使没有并发。

我们可以解决这些问题。

template<class T>
struct shared_destroyable {
  std::shared_ptr<T> lock() const {
    return atomic_load<T>(ptr.get());
  }
  explicit operator bool() const { return (bool)lock; }
  void reset( std::shared_ptr<T> pin = {} ) {
    atomic_store(ptr.get(), std::move(pin));
  }
  shared_destroyable(std::shared_ptr<T> pin):
    ptr(std::make_shared<std::shared_ptr<T>>(std::move(pin))
  {}
  shared_destroyable()=default;
  shared_destroyable(shared_destroyable&&)=default;
  shared_destroyable(shared_destroyable const&)=default;
  shared_destroyable& operator=(shared_destroyable&&)=default;
  shared_destroyable& operator=(shared_destroyable const&)=default;
private:
  std::shared_ptr<std::shared_ptr<T>> ptr;
};

这表现得像 weak_ptr shared_ptr hybrid 一样模糊。

如果最后一个消失了,则该对象被销毁。

但是,如果其中任何一个 .reset(),则只要具有 lock()ed 的最后一个其他代码结束其作用域,该对象就会被销毁

所指的作业更改。

所以在使用时你这样做:

if(auto sp = sd.lock()) {
  // use sp
}

并且sp 的生命周期保证在{} 的范围内持续,即使有人在块内、另一个线程中或调用其他方法时执行sd.reset()

【讨论】:

    【解决方案2】:

    我认为最好的解决方案是有一个包装器对象,它有一个指向实际计时器对象的唯一指针,以及一个计时器对象的 getter,如果它已被销毁,则返回 null。

    这样,如果计时器到期并被销毁,没有失去兴趣的调用者不会持有指向计时器对象的明显有效但实际上无效的指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多