4

オブジェクトに type の値が含まれている最小限の同期メカニズムを実装しようとしていますFoo。これFooは潜在的に重い型である可能性がありますが、その値を変更することはめったにありません。オブジェクトは複数のスレッドからアクセスされる可能性があり、ほぼ 100% の読み取りが行われます。

リーダーのロック要件なしでこれを機能させる方法を考えようとしています。私の最初の試みはFoo、タイプ の共有ポインター メンバーを介して、クラスに を含めることでしstd::shared_ptr<Foo>た。読み取り操作は、単純に共有ポインターをコピーして構築し、逆参照してから、値のこの「バージョン」を使用して必要なことを行います。

Foo書き込み操作は、変更を Foo の新しいコピーに適用し、完了したら、現在のバージョンを新しいバージョンに置き換えようとします。

shared_ptr<Foo>copy-constructor が何かを更新しようとして読み取り/書き込みの競合に陥り、破損した値を読み取る可能性があるため、これは不可能であることに気付きました。アトミック カウンターを使用し、CAS 操作でバージョンの更新を行うことで、この問題を回避できますが、解決boost::intrusive_ptr<Foo>できない競合状態が残っていintrusive_ptr_add_refます。カウントを 0 に下げた別のスレッドによって破棄されました。

このアプローチでは、何かが根本的に壊れているようです。

クリティカル セクション、リーダー/ライター ロック、または本格的な RCU (read-copy-update) に依存せずにこれを達成する方法はありますか? 多分私は単純なものを見逃しています。プラットフォームは Win7+/x86/x64 です。

4

2 に答える 2

4

std::shared_ptr<Foo>解決策は、最初に新しいローカルを持ち、それをアトミック割り当てメソッドを介しFooてグローバルに割り当てることです。明確にするために:単純な割り当てを使用しないでください。リンクから、次を使用できます。std::shared_ptr

atomic_store( &global_ptr, std::make_shared<Foo>(...) );
于 2013-03-09T00:52:29.047 に答える
0

これはうまくいくでしょう。

Foo * globalFoo;
.
.

Foo* newFoo = new Foo();
Foo* temp;
do {
    temp = globalFoo;
} while(! std::atomic_compare_exchange_weak(temp, globalFoo, newFoo));
于 2013-03-09T01:12:27.687 に答える