首页 > 解决方案 > 移动 std::atomic_flag 的惯用方式(或:如何移动承诺)

问题描述

我有一个围绕无限循环 std::thread 的 RAII 包装类。包装器持有一个与线程共享的std::atomic_flag/std::atomic<bool>以最终将其关闭(包装器写入;线程读取)。一切都很好,直到我需要移动 Wrapper 类,因为原子没有移动构造函数。

如何以线程安全的方式移动我的控制标志和线程

我的想法是将atomic_flaga包装起来shared_ptr并给线程一个副本。只要我不写入 shared_ptr(但只写入底层 atomic_flag),我就非常有信心它将是线程安全的。

但是,这感觉不是很惯用,我想有一种更惯用的方法来解决这个问题。在我看来,std::promise一定已经解决了类似的问题。我试图查看 libc++ 的 src 但无法轻松识别代码。

代码的示例实现与此类似(使用 Nathan 的输入更新

void run(std::atomic_bool *active) {
  while (active->load()) {
     // ...
  }
}

class RaiiThread {
public:
  RaiiThread() : t_(&run, active_.get()) {}
  RaiiThread(RaiiThread &&) = default;
  ~RaiiThread() {
    if (t_.joinable()) {
      active_->store(false);
      t_.join();
    }
  }

private:
  std::unique_ptr<std::atomic_bool> active_{
      std::make_unique<std::atomic_bool>(true)};
  std::thread t_;
};

int main() {
  RaiiThread t1;
  auto t2 = std::move(t1);
}

标签: c++multithreadingconcurrencyatomic

解决方案


推荐阅读