24

かなり単純なスレッド化されたアプリケーションを作成しようとしていますが、boost のスレッド ライブラリは初めてです。私が取り組んでいる簡単なテストプログラムは次のとおりです。

#include <iostream>
#include <boost/thread.hpp>

int result = 0;
boost::mutex result_mutex;

boost::thread_group g;

void threaded_function(int i)
{
    for(; i < 100000; ++i) {}

    {
        boost::mutex::scoped_lock lock(result_mutex);
        result += i;
    }
}

int main(int argc, char* argv[])
{
    using namespace std;

    // launch three threads
    boost::thread t1(threaded_function, 10);
    boost::thread t2(threaded_function, 10);
    boost::thread t3(threaded_function, 10);

    g.add_thread(&t1);
    g.add_thread(&t2);
    g.add_thread(&t3);

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}

ただし、このプログラムをコンパイルして実行すると、次の出力が得られます

$ ./test 
300000
test: pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
Aborted

明らかに、結果は正しいのですが、特に、本質的に同じ構造を持つ実際のプログラムが join_all() ポイントでスタックしているため、このエラー メッセージが心配です。誰かが私に何が起こっているのか説明できますか? これを行うためのより良い方法はありますか?つまり、多数のスレッドを起動し、それらを外部コンテナに保存し、プログラムを続行する前にすべてのスレッドが完了するのを待ちますか?

ご協力いただきありがとうございます。

4

4 に答える 4

29

あなたの問題は、プログラムの終了時に呼び出される thread_group デストラクタが原因だと思います。スレッド グループは、スレッド オブジェクトを破棄する責任を負いたいと考えています。boost::thread_groupのドキュメントも参照してください。

メイン関数のスコープ内のローカル変数として、スタック上にスレッド オブジェクトを作成しています。したがって、プログラムが終了し、thread_group がそれらを削除しようとすると、それらは既に破壊されています。

解決策として、 newを使用してヒープ上にスレッド オブジェクトを作成し、thread_group にそれらの破棄を処理させます。

boost::thread *t1 = new boost::thread(threaded_function, 10);
...
g.add_thread(t1);
...
于 2009-08-07T22:01:45.547 に答える
28

スレッドへのハンドルが必要ない場合は、thread_group::create_thread() を使用してみてください。これにより、スレッドを管理する必要がまったくなくなります。

// Snip: Same as previous examples

int main(int argc, char* argv[])
{
    using namespace std;

    // launch three threads
    for ( int i = 0; i < 3; ++i )
        g.create_thread( boost::bind( threaded_function, 10 ) );

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}
于 2011-07-19T22:35:40.217 に答える
3

add_thread() は、渡されたスレッドの所有権を取得します。スレッド グループはスレッドを削除します。この例では、スタックに割り当てられたメモリを削除していますが、これはかなり重大な犯罪です。

メンバー関数add_thread()

void add_thread(thread* thrd);

前提条件:

式 delete thrd は整形式であり、未定義の動作にはなりません。

効果:

thrd が指す boost::thread オブジェクトの所有権を取得し、それをグループに追加します。

事後条件:

this->size() が 1 増加します。

それがあなたのコードに問題があるのか​​ 、それとも単なるバグの例なのかはわかりません。それ以外の場合、コードは正常に見えます。

于 2009-08-07T21:06:25.363 に答える
1

上記のどれも実際に質問に答えていないようです。

同様の問題に遭遇しました。この警告 (pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->_ data. _owner == 0' failed. Aborted)の結果、プログラムがスレッドをリークし、boost_resource_error 例外が発生することがあります

その理由は、ほとんどのスレッドがまだ実行中 (終了していない) にもかかわらず、プログラムが join_all() の後も実行を続けているようです。

于 2013-07-12T13:39:51.057 に答える