10

スレッド セーフな C++ ウィーク ポインター テンプレート クラスを開発する試みでは、オブジェクトがまだ生きていることを示すフラグをチェックする必要があります。存在する場合は、オブジェクトの参照カウントをインクリメントし、両方の手順をアトミックに実行する必要があります。

_InterlockedCompareExchange() や _InterlockedIncrement() など、コンパイラによって提供される組み込み関数の存在を知っています。しかし、私が欲しいのは interlockedCompareIncrement() 関数です。少なくとも Windows x86 プラットフォームで、他のプリミティブを使用してこの組み込みをシミュレートする効率的な方法はありますか?

4

3 に答える 3

7

それvalueがフラグ変数であるとします。宣言する必要がありますvolatile

long curvalue;
long newvalue;

do
{
    curvalue = value;
    newvalue = curvalue + 1;
}
while( _InterlockedCompareExchange( &value, newvalue, curvalue ) != curvalue );

ご覧のとおり、 calculate に適用される演算を変更することで、必要なあらゆる種類の算術演算にこれを一般化できますnewvalue

2 つの値を同時に比較する場合、最善の方法は、両方の値を 1 つの変数にパックしてから、その 1 つの変数を操作することです。参照カウントと組み合わせたフラグを使用しているため、最下位ビットをvalue「アライブ」フラグとして使用し、一度に 2 ずつインクリメント/デクリメントすることをお勧めします。これにより、フラグと参照カウントの両方を 1 つの 32 ビット変数にエンコードできます。

于 2010-03-04T04:27:10.640 に答える
1

ライブラリを複数の CPU または複数のコア マシンで実行する場合は、CPU によって提供されるハードウェア サポートを使用する必要があります。ここにあなたのためのいくつかの参照があります:

http://en.wikipedia.org/wiki/Test-and-set http://software.intel.com/en-us/forums/showthread.php?t=47498

または、OS が提供するロック機構を使用する必要があります。そのような

http://msdn.microsoft.com/en-us/library/ms684841%28VS.85%29.aspx または http://en.wikipedia.org/wiki/POSIX_Threads

于 2010-03-04T04:39:19.503 に答える
0

C++ を使用しているため、独自のアセンブリ コードを記述できます。

おそらくこれは、アトミックスワップを使用してアトミックインクリメントを実装することに関連していますか?

于 2010-03-04T04:28:59.313 に答える