docdocdoc9
docdocdoc9

Reputation: 148

Static initialization in c++ and thread safety

Static initialization of class instances is not thread-safe. The code below is an example of what not to do :

extern int computesomething();

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

    int result;
};

void usecached()
{
    static cachedcomputation c;

    // use of c.result - may break
}

However, would the code below be thread-safe ? (Ignoring the ugliness of the solution) When or why would it 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 - ???
}

Upvotes: 4

Views: 289

Answers (1)

Michael Shmalko
Michael Shmalko

Reputation: 710

You need to:

  • initialize your "mutex"
  • reset "mutex" at the end of if block: InterlockedExchange(&mutex, 0)
  • optionally convert if-statement to while, so your code would block until "mutex" is unlocked

Upvotes: 3

Related Questions