13

最近、私はpdf DesigningMTprogramsを読んでいます。これは、オブジェクトがスコープ外になる前に、ユーザーがC++0xdetach()のクラスのオブジェクトを明示的に呼び出さなければならないことを説明しています。std::thread呼び出さない場合はstd::terminate()呼び出され、アプリケーションは停止します。

私は通常boost::thread、C++でのスレッド化に使用します。boost::thread私が間違っているが、オブジェクトがスコープから外れると自動的に切り離される場合は、私を訂正してください。

ブーストアプローチはRAIIの原則に従いますが、stdは従​​わないようです。

これには特別な理由があるかどうか知っていますか?

4

2 に答える 2

16

これは確かに真実であり、この選択はN3225のデストラクタに関する注記で説明されていstd::threadます。

その場合、joinable()それterminate()以外の場合は影響はありません。[注:デストラクタでスレッドを 暗黙的joinable()にデタッチまたは結合すると、例外が発生した場合にのみ発生する正確性(デタッチの場合)またはパフォーマンス(結合の場合)のバグのデバッグが困難になる可能性があります。したがって、プログラマーは、スレッドがまだ参加可能である間は、デストラクタが実行されないようにする必要があります—エンドノート]

どうやら委員会は2つの悪のうちの小さい方に行きました。


編集私はちょうど最初の言葉遣いがなぜであるかを説明するこの興味深い論文を見つけました:

その場合、joinable()それdetach()以外の場合は影響はありません。

以前に引用したものに変更されました。

于 2010-12-22T10:35:53.757 に答える
3

RAIIスレッドを実装する1つの方法は次のとおりです。

#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());

これを使用してスレッドを切り離す場合は、最初にこれを読んでください。

于 2013-02-28T16:19:18.993 に答える