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的主要内容,如果未能解决你的问题,请参考以下文章