这些天我正在阅读 pdf设计 MT 程序。它解释说,用户必须在 C++0xdetach()
中的类std::thread
对象超出范围之前显式调用该对象。如果您不调用它将std::terminate()
被调用并且应用程序将死亡。
我通常boost::thread
用于 C++ 中的线程。如果我错了,请纠正我,但是当boost::thread
对象超出范围时会自动分离。
在我看来,boost 方法遵循 RAII 原则,而 std 没有。
你知道这是否有什么特别的原因吗?
这些天我正在阅读 pdf设计 MT 程序。它解释说,用户必须在 C++0xdetach()
中的类std::thread
对象超出范围之前显式调用该对象。如果您不调用它将std::terminate()
被调用并且应用程序将死亡。
我通常boost::thread
用于 C++ 中的线程。如果我错了,请纠正我,但是当boost::thread
对象超出范围时会自动分离。
在我看来,boost 方法遵循 RAII 原则,而 std 没有。
你知道这是否有什么特别的原因吗?
这确实是真的,这个选择在 N3225 中关于std::thread
destructor 的注释中进行了解释:
如果
joinable()
thenterminate()
,否则没有效果。[注意:在其析构函数中 隐式分离或加入joinable()
线程可能导致难以调试正确性(分离)或性能(加入)错误,仅在引发异常时遇到。因此,程序员必须确保在线程仍可连接时永远不会执行析构函数。——尾注]
显然,委员会选择了两害相权取其轻。
编辑我刚刚发现这篇有趣的论文解释了为什么最初的措辞:
如果
joinable()
thendetach()
,否则没有效果。
已更改为先前引用的。
这是实现 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());
如果您想使用它来分离线程,请先阅读此内容。