0
tbb::tbb_thread*                    m_tbbTimerThread;
m_tbbTimerThread = new tbb::tbb_thread(&sFirstTimerBlocked, this);

// 上記のスレッドが生成されます。

後で別の機能でスレッドを削除したい。以下のようにしています。

if(m_tbbTimerThread != NULL ) 
{
    delete m_tbbTimerThread;
}

m_tbbTimerThread = NULL;

これは正しい方法ですか?

ありがとう!

4

1 に答える 1

2

あなたの「正しい」観念次第です。

一般に、実行中のスレッドに接続されたままのスレッド オブジェクトを破棄することはお勧めできません。C++11 では、これを試みるとstd::threadが呼び出されます。std::terminateTBB ははるかに寛容です (スレッドは破棄時に単純に切り離されます) が、根本的な問題がなくなるわけではありません。

特に、クリーン シャットダウンを保証する最後のチャンスを失う可能性があります。プロセスが終了した場合、デタッチされたスレッドがディスクに何かを書き込んでいないことをどのように保証できますか? 明示的にクリーンアップせずにスレッドが終了した場合にリークする永続的なハンドルを保持しないことをどのように保証できますか? 親プロセスが死んでいるためにスレッドが強制終了された場合、RAII はおそらく起動しません。一般に、スレッドのデタッチは、最も単純なスレッドを除いて、非常に問題があります。

したがって、おそらく「より正しい」シャットダウン方法は次のようになります。

if(m_tbbTimerThread != NULL ) 
{
    if(m_tbbTimerThread->joinable()) {
        <notify the thread to shutdown>
        m_tbbTimerThread->join();
    }
    delete m_tbbTimerThread;
}

非ブロッキング スレッドの場合、シャットダウン通知を実装するには、1 つのアトミック フラグで十分な場合があります。

すべてのルールと同様に、例外があります。監視の責任を別のオブジェクトに移すことができる場合があります。その場合、スレッドを切り離しても問題ない場合があります。たとえば、C++11std::async呼び出しは新しいスレッドを生成し、スレッドが終了すると準備が整う Future を返します。未来を待つことは、スレッドに参加することと同じ目的を果たします。そのため、 がasync明示的なスレッド オブジェクトを返す必要はありません。

于 2013-07-25T10:38:28.073 に答える