yohhoyの日記

技術的メモをしていきたい日記

threadのdetachとデストラクタ

C++11標準ライブラリに追加された std::thread と、Boost.Thread提供の boost::thread では、デストラクタの動作仕様が少し異なる。(Boost 1.48.0を対象とする)

2013-02-05追記:記事内容にBoost.Thread 1.50.0〜1.56.0までの破壊的変更を伴う移行措置を反映。1.54.0で既定動作の変更が予告されていることに注意。*1

  • C++11(std::thread)では、join/detachのどちらも行わないままthreadオブジェクトを破棄しようとすると、std::terminate()が呼び出されてプログラムが終了してしまう。
  • [1.53.0以前の既定動作/1.56.0まで選択可能]Boost.Thread(boost::thread)では、threadオブジェクトの破棄時にdetachが呼ばれる。
  • [1.54.0以降の既定動作/1.50.0から選択可能]Boost.Thread(boost::thread)でもC++11標準ライブラリ(std::thread)と同じ動作となる。
void func();

//-------- C++11 std::thread
#include <thread>
void call() {
  std::thread th(func);
  // th.join()もth.detach()も行っていないため、
  // std::terminate()によりプログラムが終了する。
}

//-------- Boost.Thread boost::thread
#include <boost/thread/thread.hpp>
void call() {
  boost::thread th(func);
  // thオブジェクト破棄時にth.detach()が自動的に行われる。
  // 該当スレッドの実行は本関数を抜けた後も継続されている。
}

N3337 30.3.1.3より引用。

~thread();
If joinable(), calls std::terminate(). Otherwise, has no effects. [Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. -- end note]

Boost.Thread - Thread Managament - Thread Destructor

Effects: If *this has an associated thread of execution, calls detach(). Destroys *this.

関連URL

*1:1.54.0にてBOOST_THREAD_VERSIONマクロ既定値が 2 → 3 に変更される予定。なお、1.52.0リリース時点では1.53.0での破壊的変更の予定が延期された経緯がある。