0

オブジェクトを更新するスレッドセーフな方法を提供しようとしています。それについての投稿をいくつか見ましたが、私の質問に 100% 答えているものはありません。

私がやりたいことは、「m_First」というポインターを維持して、自分のデータを指すことです。誰かが get を呼び出した場合、私はそのポインターを尊重し、それが指すオブジェクトへの参照を返します。

誰かが新しいオブジェクトへのポインターを渡して set を呼び出した場合、そのポインターをリストに追加し、新しいオブジェクトを指すように m_First を更新します。

オブジェクトをベクトルに格納して、完了時にメモリをクリーンアップできるようにします。

現在、私はこれらのメンバーを定義しています:

std::vector<MyObject*> m_List;
const MyObject* m_First;

最初はこのように初期化されます。m_First = m_List.back();

複数のスレッドが m_First を読み取り、複数のスレッドが m_First に書き込みできるようにしたいと考えています。

私のクラスには2つのメソッドがあります

MyObject& getMyObject() {return *m_First;}

void setMyObject(MyObject* newObj) {

  m_List.push_back(newObj); // add to list so we can later cleanup mem

  do {
    Node* oldHead = m_First;
  } while (!__sync_bool_compare_and_swap(m_First, *oldHead, *newObj));
}

私が疑問に思っているのは、get メソッドのスレッドセーフで *m_First を返すことです。つまり、別のスレッドが m_First を更新しようとしている間に、これを安全に逆参照してオブジェクトへの参照を返すことはできますか、それとも m_First を読み取るためにある種のアトミック メソッドを使用する必要がありますか。

アドバイス/ヘルプをいただければ幸いです。

4

2 に答える 2

0

値がレジスタからではなくメモリから読み取られることを確認するには、アトミック読み取りを実行する必要があります。

これを達成するにはさまざまな方法があります。一部のシステムでは、アラインされたワード サイズの値を揮発性ポインタ キャストを通じて読み取ること*(const volatile MyObject*)pができます。しかし、組み込みのアトミック操作を既に使用しているので__sync_add_and_fetch、0 を追加したようなものを利用することができます。

于 2012-07-13T17:10:55.223 に答える
0

複数のスレッドが m_First を読み取り、複数のスレッドが m_First に書き込みできるようにしたいと考えています。

複数のスレッドはどのように に書き込みm_Firstますか? それが終わった場合setMyObject、それらはすべてm_Listベクトルを同時に変更します。これはデータ競合となり、ほぼ確実にベクトルが破損します。

于 2012-07-13T17:17:41.890 に答える