【问题标题】:thread destructors in C++0x vs boostC ++ 0x中的线程析构函数与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 没有。

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

【问题讨论】:

    标签: c++ c++11 boost-thread


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      相关资源
      最近更新 更多