4

クラス インスタンスの静的初期化は、スレッド セーフではありません。以下のコードは、してはいけないことの例です。

extern int computesomething();

class cachedcomputation
{
public:
    cachedcomputation()
    {
        result = computesomething();
    }

    int result;
};

void usecached()
{
    static cachedcomputation c;

    // use of c.result - may break
}

ただし、以下のコードはスレッドセーフでしょうか? (解決策の醜さを無視して) いつ、またはなぜ壊れるのですか?

extern int computesomething();

class cachedcomputation
{
public:
    cachedcomputation()
    {
    if(0==InterlockedCompareExchange(&mutex, 1, 0))
    {
        // first thread
            result = computesomething();
        InterlockedExchange(&mutex, 2);
    }
    else
    {
        // other thread - spinlock until mutex==2
        while(2!=InterlockedCompareExchange(&mutex, 2, 2)){}
    }
    }

    int result;

private:
    long mutex;
};

void usecached()
{
    static cachedcomputation c;

    // use of c.result - ???
}
4

1 に答える 1

3

必要がある:

  • 「ミューテックス」を初期化します
  • if ブロックの最後にある "mutex" をリセット: InterlockedExchange(&mutex, 0)
  • オプションで if ステートメントを while に変換すると、「mutex」のロックが解除されるまでコードがブロックされます
于 2012-11-12T05:18:16.290 に答える