3

次のコードがあるとしましょう。

void* p0 = nullptr;
void* p1 = alloc_some_data();
void f1() {
    p0 = p1;
    p1 = nullptr;
}

スレッド1で実行されていると仮定f1します(コードをそのままにして)別のスレッドが、ある時点で(p0コンパイラまたはハードウェアが最初の割り当ての前に2番目の割り当てなどの命令を並べ替える場合)と見なす可能性はありますか?p1nullptr

これを尋ねる理由は、ガベージコレクターを実装し、アトミック命令()を使用してGCスレッドからポインターにアクセスする必要があるかどうかを知りたいためですstd::atomic。GCスレッドが認識していれば問題はありませんが、GCスレッドが認識していればp0 == p1 == alloc_some_data()問題が発生p0 == p1 == nullptrします。これは、明らかに到達可能である場合、p1で以前のデータが到達不能として報告されるためです。

4

3 に答える 3

2

同期せずに別のスレッドによって書き込まれたオブジェクトを1つのスレッドで読み取ると、データ競合が発生します。これは明らかに、ガベージコレクターが何らかの同期を使用して値を読み取る必要があることを意味します。元の質問に関して:コードにはp0、の書き込みの前にへの書き込みが表示されることを示すものはありませんp1。つまり、別のスレッドは、実際、両方がnullであると見なすことができます。これは、別のスレッドとの通信に使用される同期プリミティブとは無関係です。これら2つの書き込みの間に順序はありません。

于 2012-09-17T00:33:33.240 に答える
0

はい。必ずしも可能性は低いですが、これらの操作はアトミックではないため、完全に可能です。

(いくつかの可能なシナリオの1つ)はこれです:

Thread 2: Get value of p0 (null)

Thread 1: Get value of p1 (non-null)
          p0 = p1
          p1 = nullptr

Thread 2: Get value of p1 (null)

何らかの形式のアクセス制御(つまり、ミューテックス)を使用する必要があります。

于 2012-09-17T00:35:53.783 に答える
0

あなたの質問への答えはイエスですが、それはコンパイラとCPUに依存します。私はあなたも作る必要があると思いますp0そしてp1揮発性。並べ替えを停止するには、_mm_sfenceおよび_mm_lfenceinstrinsics(x86 / x64の場合)を使用できます。

于 2012-09-17T00:37:57.177 に答える