2016-04-17 7 views
5

xが共有スレッド間変数であり、funcが常に0を返すと仮定すると、以下のコードにはC11とC++ 11のデータ競合が含まれていますか? xは、以下のswitch文を除いて、常に適切なロックを持つ2つの異なるスレッドで書かれているとします。共有変数への保護されていないアクセスは常にデータ競合ですか?

int x; // global variable 

... 

int y; // local variable 

... 

switch (func()) 
{ 
    case 1: 
    { 
    x = 0; 
    y = 1; 
    break; 
    } 
    case 2: 
    { 
    x = 0; 
    y = 2; 
    break; 
    } 
    case 3: 
    default: 
    { 
    y = 3; 
    break; 
    } 
} 

標準には(C11とC++ 11の両方)、コードにデータ競合を導入するコンパイラの変換を防ぐメモがあります。コンパイラは以下のようなコードを変換できますか?以下のコードは確かにデータ競合を含んでいますが、コンパイラがそれを導入したのか、それとも既に元のコードであったのかという疑問があります。共有変数にはアクセスできないが、保護されていないアクセスがありました。 C++標準で

int x; // global variable 

... 

int y; // local variable 

... 

temp = x; 
x = 0; 
switch (func()) 
{ 
    case 1: 
    { 
    y = 1; 
    break; 
    } 
    case 2: 
    { 
    y = 2; 
    break; 
    } 
    case 3: 
    default: 
    { 
    x = temp; 
    y = 3; 
    break; 
    } 
} 
+0

のデフォルトセクション内の任意の同期メカニズムは、データレースを期待していなければ、そうあなたは、むしろ 'のstd ::原子 Xを持つ必要があります;' –

+0

はい、絶対に –

+0

それだけではありません。データ競合Cはコンカレントプロセスのコンセプトを持っていません – Olaf

答えて

4

、レースが定義される:

1.10/4: 2件の発現の評価競合それらの一方がメモリ位置を変更し、他の一つはアクセス又は を変更する場合同じメモリ位置。

1.10/21:プログラムの実行は、それは別のスレッドで、相反する2つのアクションが含まれている場合、データ競合が含まれていないアトミックではありません の少なくとも1つ、どちらも他の前に起こります。そのような データ競合は、未定義の動作をもたらします。

あなたが原因func()は常に0(あなたの主張を)返すという事実に、同じコードを実行している複数のスレッドを持っていると仮定すると、スレッドはいずれも、xの内容を変更することができませんでした。さらに、yはスレッドによって実行される関数のローカル変数なので、共有されません。したがって、このシナリオで競合状態は発生しません。

コンパイラは、第二のスニペットに対応する変換を行うことが許可されていない

理由:

1.10/22:により改変されないであろう潜在的に共有メモリロケーションへの割り当てを導入コンパイラ変換 アブストラクトマシンの実行では がデータ競合に遭遇しなかった場合に、別のスレッドによって別の割り当てを上書きする可能性があるため、抽象マシンはこの規格では一般的に排除されます。

自身がスニペットを書く場合、xがアトミックではありませんので、しかし、条件の下でレース条件が発生する場合があります上記で説明し、(どちらかx=0が一つのスレッド(temp=x)で読み取りアクセス権、およびその他で書き込みアクセスをすることができ。または他のスレッド(x=temp

+0

答えをありがとう、これは私が期待するものですが、私は一点で疑問があります。私は、* func *が常に0を返すという事実が、switch文のxへの代入と、別のスレッドのxへの他のアクセスとの間の*前後関係にどのように影響するのか理解していません。 – mrn

+1

@mrn同期が提供するもの以外のスレッド間にはhapppens-beforeはありません。 – Yakk

+0

Happen-Beforeリレーションシップは、実行中のスレッド同期から発生するシーケンシング伝播を分析するためのツールです。スレッドのどれも共有変数を使用していない場合、残りの部分が初期値になったこと以外の順序付け効果はありません。ちなみに、あなたのコードではシンクロが表示されません。xはアトミックではありません。 functが0以外の何かを返すと、その変数へのアクセスの順序を保証するものがないため、競合が発生する可能性があります。 – Christophe

関連する問題