質問

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

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

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

そのため、スレッド 1 がポインタを使用している間に、スレッド 2 がポインタを削除する可能性があります。汚い。

したがって、代わりに Boost 共有 PTR のコンテナを使用したいと思います。IIRC では、これらのポインターは参照カウントされるため、生のポインターではなく共有 ptr を返す限り、コンテナーから 1 つを削除しても、最後に使用されるまでスコープ外になるまで実際には解放されません。つまり

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];
}

上記の例では、スレッド 2 が Erase を呼び出す前にスレッド 1 がポインターを取得した場合、指すオブジェクトはまだ有効ですか?スレッド1が完了しても実際には削除されないのでしょうか? グローバル ベクターへのアクセスはクリティカル セクション経由であることに注意してください。

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

役に立ちましたか?

解決

boost::shared_ptr のスレッドの安全性については、チェックする必要があります。 このリンク. 。安全であることは保証されていませんが、多くのプラットフォームで動作します。私の知る限り、std::vector の変更は安全ではありません。

他のヒント

上記の例では、スレッド 2 が Erase を呼び出す前にスレッド 1 がポインターを取得した場合、指すオブジェクトはまだ有効ですか?スレッド1が完了しても実際には削除されないのでしょうか?

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top