32

について質問がありboost::shared_ptr<T>ます。

スレッドがたくさんあります。

using namespace boost;

class CResource
{
  // xxxxxx
}

class CResourceBase
{
public:
   void SetResource(shared_ptr<CResource> res)
   {
     m_Res = res;
   }

   shared_ptr<CResource> GetResource()
   {
      return m_Res;
   }
private:
   shared_ptr<CResource> m_Res;
}

CResourceBase base;

//----------------------------------------------
// Thread_A:
    while (true)
    {
       //...
       shared_ptr<CResource> nowResource = base.GetResource();
       nowResource.doSomeThing();
       //...
    }

// Thread_B:
    shared_ptr<CResource> nowResource;
    base.SetResource(nowResource);
    //...

Q1

Thread_Aが最新であることを気にしない場合nowResource、コードのこの部分に問題はありますか?

つまり、 Thread_BSetResource()が完全ではない場合、 Thread_Aは間違ったスマート ポイントを取得しGetResource()ます。

Q2

スレッドセーフとはどういう意味ですか?

リソースが最新かどうかを気にしないshared_ptr<CResource> nowResource場合、 がリリースされたときにプログラムがクラッシュするか、それともnowResource問題によって が破壊されshared_ptr<CResource>ますか?

4

5 に答える 5

33

ブーストのドキュメントから:

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

それ以外の同時アクセスは、未定義の動作を引き起こします。

の同時読み取りと書き込みを使用するため、使用法は安全ではありませんm_res。ブースト ドキュメントの例 3もこれを示しています。

in /へのアクセスを保護する別のミューテックスを使用する必要があります。m_resSetResourceGetResource

于 2009-03-28T08:27:34.170 に答える
3

まあ、tr1::shared_ptr (boost に基づく) のドキュメントは別の話をしています。つまり、リソース管理はスレッド セーフですが、リソースへのアクセスはそうではありません。

"...

スレッドセーフ

C++0x のみの機能は、rvalue-ref/move サポート、アロケーター サポート、エイリアシング コンストラクター、make_shared および allocate_shared です。さらに、auto_ptr パラメーターを使用するコンストラクターは、C++0x モードでは非推奨です。

Boost shared_ptr ドキュメントのスレッド セーフティ セクションには、「shared_ptr オブジェクトは、組み込み型と同じレベルのスレッド セーフを提供する」と記載されています。実装では、インスタンスが参照カウントを共有している場合でも、個別の shared_ptr インスタンスへの同時更新が正しいことを確認する必要があります。

shared_ptr a(新しい A); shared_ptr b(a);

// スレッド 1 // スレッド 2

設定されています(); b.reset();

動的に割り当てられたオブジェクトは、スレッドの 1 つだけによって破棄される必要があります。弱参照は物事をさらに面白くします。shared_ptr の実装に使用される共有状態は、ユーザーに対して透過的である必要があり、不変条件は常に保持される必要があります。共有状態の重要な要素は、強い参照カウントと弱い参照カウントです。これらの更新はアトミックであり、管理されたリソースの正しいクリーンアップを保証するためにすべてのスレッドから見えるようにする必要があります (これは結局のところ、shared_ptr の仕事です!)管理対象リソースの競合はありません。

...」

http://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.shared_ptrを参照して ください

于 2010-12-08T13:45:43.540 に答える
1

m_Resはスレッドセーフではありません。同時読み取り/書き込みであるため、保護するには boost::atomic_store/load 関数が必要です。

//--- Example 3 ---
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write
于 2016-06-13T03:25:20.673 に答える
-1

さらに、クラスにはCyclic-references条件があります。のshared_ptr<CResource> m_ResメンバーになることはできませんCResourceBase。代わりに使用できますweak_ptr

于 2010-06-15T02:46:24.970 に答える