7

私はしばらくの間答えを見つけようとしていましたが、失敗しました。

shared_ptr1つのスレッドから作成されたと仮定しましょう。次に、これshared_ptrを別の2つのスレッドに渡します(たとえば、いくつかのキューを使用します)。したがって、この瞬間shared_ptrから、同じ生のポインタを指す、元の2つのコピーがあります。両方の所有者スレッドは、これのコピーをshared_ptrキューから取得します。次に、それを別のスレッドに渡すか、破棄します。

質問は-それは安全ですか?生のポインターは正しく破棄されますか(参照カウンターへの競合はありませんか?) ここに画像の説明を入力してください

4

3 に答える 3

9

C ++標準には、スレッドセーフに関する保証はほとんどありません。の参照カウントstd::shared_ptrは唯一の例外です。アトミックにアクセスされる変数として動作することが保証されています。私はこれが§20.7.2.2/4のこのフレーズで成文化されていると信じています:

の変更は、use_count()データの競合を引き起こす可能性のある変更を反映していません。

boost::shared_ptr 同じ保証を提供します

shared_ptrオブジェクトは、組み込み型と同じレベルのスレッドセーフを提供します。shared_ptrインスタンスは、複数のスレッドによって同時に「読み取る」ことができます。異なるshared_ptrインスタンスを複数のスレッドで同時に「書き込む」ことができます(これらのインスタンスがコピーであり、その下で同じ参照カウントを共有している場合でも)。

于 2012-07-15T12:29:53.650 に答える
5

ブーストドキュメントの状態:

異なるshared_ptrインスタンスは、複数のスレッドによって同時に「書き込み」(operator =やresetなどの可変操作を使用してアクセス)できます(これらのインスタンスがコピーであり、その下で同じ参照カウントを共有している場合でも) 。

(強調鉱山)

したがって、ここで重要なのは、スレッド間でsをコピーするかどうかです。boost::shared_ptrコピーを作成する場合(sを使用する「安全な」方法shared_ptr)、スレッドセーフについて心配する必要はありません。shared_ptrただし、参照またはポインタを渡すためshared_ptr、異なるスレッドで実際に同じものを使用している場合は、ドキュメントで説明されているように、スレッドセーフについて心配する必要があります。

于 2012-07-15T12:57:05.733 に答える
0

複数のスレッドのユースケースでのブースト共有ポインターでの参照カウントについてのコメントを投稿したいと思います。コメントは、「ブースト共有ポインタ参照カウントに競合状態はありますか?」という質問に答えることです。</ p>

私の簡単な答えは、少なくともほとんどの主流コンパイラのブースト1.35の後は、「いいえ」です。boost / detail/shared_count.hppで定義されている「add_ref_copy」と呼ばれるブースト実装。この関数は、個々のコンパイラに対して定義された対応するアトミック関数を呼び出します。たとえば、Windowsバージョンは「BOOST_INTERLOCKED_INCREMENT」を呼び出して、アトミックな方法でカウントをインクリメントします(詳細はdetail \ sp_counted_base_w32.hppを参照)。また、X86用のLinux gccはatomic_increment(…)を呼び出します(詳細については、detail \ sp_counted_base_gcc_x86.hppを参照してください)。個々のコンパイラは、参照カウントが効率的に更新されるように、スレッドセーフメカニズムを実装しました。一部のコードはアセンブリでさえ書かれています。

今、私の簡単な答えには注意点があります。複数のスレッドセーフな参照カウントのために、コンパイラがブーストの祝福されたリストに含まれていることを確認する必要があります。よくわからない場合は、ブーストを駆動してpthreadライブラリを使用して参照カウントをアトミックに更新する「BOOST_SP_USE_PTHREADS」を定義できます(pthreadソリューションにboost / detail / sp_counted_base_pt.hppを含めることにより)。

于 2014-04-19T19:39:10.667 に答える