在 C++11 智能指针中存储一个 std::thread

Storing an std::thread in C++11 smart pointer

C++ 11 及以上 std::thread 直接存储为 class 的成员时,优点或缺点是什么 如下所示:

std::thread my_thread;

与像这样将 std::shared_ptrstd::unique_ptr 存储到线程相反:

std::shared_ptr<std::thread> my_thread_ptr;

是否有任何代码选项比其他代码选项更好?或者没关系,只是处理线程对象的两种不同方式。

如果您可以选择将 std::thread 作为成员变量,那就去做吧。如果没有,请考虑其他选择。不要将其包裹在 std::shared_ptrstd::unique_ptr 内,除非您有重要的理由这样做。鉴于 std::thread 本身是可移动的,因此不太可能需要将其包装到智能指针中。

使用指针(或智能指针)成员可能有一些不太常见的原因,但对于常见用法,std::thread 似乎不适用或本身就足够灵活:

  • 我们可能希望更好地控制对象的生命周期,例如初始化它 "lazily"。 std::thread 已经支持了。它可以在 "not representing a thread" 状态下创建,稍后在需要时分配真正的线程,并且必须在销毁之前显式 joined 或 detacheded。
  • 我们可能希望转让成员 to/from 一些其他所有权。不需要指针,因为 std::thread 已经支持移动和交换。
  • 我们可能希望指向的对象是动态多态的。这不适用,因为 std::thread 没有任何虚拟成员函数。
  • 我们可能需要不透明的指针来隐藏实现细节和减少依赖,但是std::thread是标准库class所以我们不能让它不透明。
  • 我们可能希望共享所有权。那是 std::thread 的脆弱场景。可以分配、交换、分离或加入它的多个所有者(并且没有太多其他线程操作)可能会导致复杂化。
  • if (xthread.joinable()) xthread.join();xthread.detach();一样,销毁前有强制清理。这在拥有 class 的析构函数中也更健壮且更易于阅读,而不是将相同的东西插入智能指针的删除器中的代码。

所以除非有一些不常见的原因,否则我们应该直接使用线程作为数据成员。