3

以下のコード スニペットでは、特定の値が変更されたときにスレッドによって SetValue() が呼び出され、その値を取得するために別のスレッドによって GetValue() が呼び出されます。私の質問は、GetValue() が誤った結果を返す状況はありますか?

double g_value[2];

// Thread one calls this to set the value
void SetValue( double value )
{
    g_value[0] = value;
    g_value[1] = value;
}

// Thread two calls this to get the value
double GetValue()
{
    double value[2];
    do
    {
        value[0] = g_value[0];
        value[1] = g_value[1];
    }
    while ( value[0] != value[1] );

    return value[0];
}
4

2 に答える 2

3

これが妥当な結果につながるという C 標準による保証はありません。あなたが書いたように、コンパイラがグローバル変数の最後に保存された値を知っているという印象を持っている場合、最適化の対象になることさえあります。

しかし、グローバル変数volatileを宣言したとしても、驚くべきことがあります。比較の結果は、キャッシュ ライン、キャッシュの一貫性、部分的な読み込みなど、簡単には制御できないさまざまな要素に依存します。さらに、結果は完全にアーキテクチャに依存します。

最新の C、別名 C11 は、_Atomic達成したいタスクを備えており、最新のプロセッサはすべてアトミック機能をサポートしています。これらを使用するか、ミューテックス、読み書きロックなどで変数を保護してください。

于 2013-08-19T06:20:30.740 に答える
1

ロックレススレッドに興味がある場合は、このリンクを確認してください。ただし、事前に定義された前提について詳しく調べてください。これは、実装にとって非常に重要です。

于 2013-08-19T06:19:40.343 に答える