1

マルチスレッド アプリケーションで使用されるポインターのコンテナー (std::vector) があるとします。コンテナーに新しいポインターを追加するとき、コードはクリティカル セクション (boost::mutex) を使用して保護されます。すべて順調です。コードは、処理のためにこれらのポインターの 1 つをスレッドに返すことができるはずですが、別の別のスレッドが、まだ使用されている可能性があるこれらのポインターの 1 つを削除することを選択する可能性があります。例えば:

thread1()
{
    foo* p = get_pointer();
    ...
    p->do_something();
}

thread2()
{
    foo* p = get_pointer();
    ...
    delete p;
}

そのため、thread1 が使用している間に、thread2 がポインターを削除する可能性があります。汚い。

代わりに、Boost 共有 ptr のコンテナーを使用したいと考えています。IIRC これらのポインターは参照カウントされるため、未加工のポインターではなく共有ポインターを返す限り、コンテナーからポインターを削除しても、最後の使用が範囲外になるまで実際には解放されません。すなわち

std::vector<boost::shared_ptr<foo> > my_vec;

thread1()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    sp->do_something();
}

thread2()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    my_vec.erase(my_vec.begin());
}

boost::shared_ptr<foo> get_ptr(int index)
{
    lock_my_vec();
    return my_vec[index];
}

上記の例で、thread2 が erase を呼び出す前に thread1 がポインターを取得した場合、指しているオブジェクトは引き続き有効でしょうか? thread1 が完了しても実際には削除されませんか? グローバル ベクトルへのアクセスは、クリティカル セクションを介して行われることに注意してください。

これが shared_ptrs の仕組みだと思いますが、確認する必要があります。

4

3 に答える 3

3

boost::shared_ptr のスレッド化の安全性については、このリンクを確認してください。安全性は保証されていませんが、多くのプラットフォームで動作します。std::vector の変更は安全ではありません。

于 2008-09-22T10:53:10.780 に答える
1

上記の例で、thread2 が erase を呼び出す前に thread1 がポインターを取得した場合、指しているオブジェクトは引き続き有効でしょうか? thread1 が完了しても実際には削除されませんか?

あなたの例では、スレッド1がスレッド2の前にポインターを取得した場合、スレッド2は関数の開始時に待機する必要があります(ロックのため)。したがって、はい、指しているオブジェクトは引き続き有効です。ただし、最初の要素にアクセスする前に、 my_vec が空でないことを確認したい場合があります。

于 2008-09-22T12:15:58.303 に答える
0

さらに、ベクトルへのアクセスを同期する場合 (元の生ポインターの提案のように)、使用法は安全です。そうしないと、他の回答者が提供したリンクの例 4 に違反する可能性があります。

于 2008-09-22T11:40:33.477 に答える