C ++ 0x中的线程析构函数与boost

Posted

技术标签:

【中文标题】C ++ 0x中的线程析构函数与boost【英文标题】:thread destructors in C++0x vs boost 【发布时间】:2011-05-29 08:02:11 【问题描述】:

这些天我正在阅读 pdf Designing MT programs 。它解释说,用户必须在 C++0x 中的 std::thread 类对象上显式调用 detach(),然后该对象超出范围。如果你不调用它std::terminate() 将被调用并且应用程序将会死掉。

我通常使用boost::thread 在 C++ 中进行线程化。如果我错了,请纠正我,但 boost::thread 对象在超出范围时会自动分离。

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

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

【问题讨论】:

【参考方案1】:

确实如此,这个选择在 N3225 中关于 std::thread 析构函数的注释中进行了解释:

如果joinable()terminate(),否则无效。 [ 注意: 隐式分离或加入 一个joinable() 线程在其 析构函数可能导致困难 调试正确性(用于分离)或 性能(加入)错误 仅在出现异常时遇到 提高。 因此程序员必须 确保析构函数永远不会 在线程静止时执行 可加入——尾注 ]

显然委员会采取了两害相权取其轻的做法。


编辑我刚刚找到this interesting paper,这解释了为什么最初的措辞:

如果joinable()detach(),否则无效。

已更改为先前引用的。

【讨论】:

为什么不在构造函数中加入 join_on_destruction 或 detach_on_destruction 标志,或者以其他方式明确指定其行为。 有一篇有趣的论文here 嗨 IceCrime。谢谢你的论文。因此,基本上杀死应用程序是引发有关线程错误的标志的最明显方式。我想说的是有趣且真正“防御性”的方式。 :)【参考方案2】:

这是实现 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());

如果你想用它来分离线程,read this first。

【讨论】:

以上是关于C ++ 0x中的线程析构函数与boost的主要内容,如果未能解决你的问题,请参考以下文章

C语言里面构造函数和析构函数的运用办法

C ++:与方法的联合?

C++--继承中的构造与析构父子间的冲突

迭代器和简单的赋值/析构函数

可连接 std::thread 的析构函数

C++中基类的析构函数为什么要用virtual虚析构函数