13

这些天我正在阅读 pdf设计 MT 程序。它解释说,用户必须在 C++0xdetach()中的类std::thread对象超出范围之前显式调用该对象。如果您不调用它将std::terminate()被调用并且应用程序将死亡。

我通常boost::thread用于 C++ 中的线程。如果我错了,请纠正我,但是当boost::thread对象超出范围时会自动分离。

在我看来,boost 方法遵循 RAII 原则,而 std 没有。

你知道这是否有什么特别的原因吗?

4

2 回答 2

16

这确实是真的,这个选择在 N3225 中关于std::threaddestructor 的注释中进行了解释:

如果joinable()thenterminate(),否则没有效果。[注意:在其析构函数中 隐式分离或加入joinable()线程可能导致难以调试正确性(分离)或性能(加入)错误,仅在引发异常时遇到。因此,程序员必须确保在线程仍可连接时永远不会执行析构函数——尾注]

显然,委员会选择了两害相权取其轻。


编辑我刚刚发现这篇有趣的论文解释了为什么最初的措辞:

如果joinable()thendetach(),否则没有效果。

已更改为先前引用的。

于 2010-12-22T10:35:53.757 回答
3

这是实现 RAII 线程的一种方法。

#include <memory>
#include <thread>

void run() { /* thread runs here */ }

struct ThreadGuard
{
    operator()(std::thread* thread) const
    {
        if (thread->joinable())
            thread->join(); // this is safe, but it blocks when scoped_thread goes out of scope
        //thread->detach(); // this is unsafe, check twice you know what you are doing
        delete thread;
    }
}

auto scoped_thread = std::unique_ptr<std::thread, ThreadGuard>(new std::thread(&run), ThreadGuard());

如果您想使用它来分离线程,请先阅读此内容

于 2013-02-28T16:19:18.993 回答