2012-11-12 48 views
4

类实例的静态初始化不是线程安全的。下面的代码是不能做的一个例子:C++中的静态初始化和线程安全

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 - ??? 
} 

回答

3

您需要:如果在块结束

  • 初始化 “互斥”
  • 复位 “互斥”:InterlockedExchange(&互斥,0)
  • 可选择转换如 - 声明为while,所以你的代码会阻塞,直到“互斥锁”解锁
+0

1 - 默认情况下,静态应该将其设置为0? 2&3 - 我希望计算器只能被调用一次。修改解决方案以将其考虑在内并使其更清晰 – docdocdoc9

+0

'long mutex'本身不是静态的,并且从不分配。 'cachedcomputation():mutex(0)'是初始化'mutex'的一种简单方法。 –

+0

@MichaelSh你为什么重置“互斥量”为零? – yohjp