2010-05-30 60 views
0

我很好奇下面的代码:函数中的静态对象是否引入潜在的竞争条件?

class MyClass 
{ 
public: 
    MyClass() : _myArray(new int[1024]) {} 
    ~MyClass() {delete [] _myArray;} 

private: 
    int * _myArray; 
}; 

// This function may be called by different threads in an unsynchronized manner 
void MyFunction() 
{ 
    static const MyClass _myClassObject; 
    [...] 
} 

有没有在上面的代码中可能的竞争条件?具体来说,编译器是否可能生成等同于以下内容的代码,“幕后”?

void MyFunction() 
{ 
    static bool _myClassObjectInitialized = false; 
    if (_myClassObjectInitialized == false) 
    { 
     _myClassObjectInitialized = true; 
     _myClassObject.MyClass(); // call constructor to set up object 
    } 
    [...] 
} 

...在这种情况下,如果两个线程都调用MyFunction的()几乎同时地,然后_myArray可能会分配两次,导致内存泄漏?

或者这是否正确处理?

+1

许多受骗者包括http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-ac-function – 2010-05-30 17:12:55

+1

的这大概也与此有关:HTTP:/ /stackoverflow.com/questions/1661529/is-meyers-implementation-of-singleton-pattern-thread-safe – 2010-05-30 19:46:57

回答

1

那里绝对有可能的竞争条件。是否真的有一个是非常不明确的。你不应该在单线程场景中使用这样的代码,因为这是糟糕的设计,但它可能是你的应用程序在多线程中死亡。任何静态的const都应该放在方便的名字空间中,并在应用程序的开始处分配。

+0

-1。将静态函数放在函数中是C++中单例的基础,有时候你不想为每个程序运行构建全局的开销付费。此外,全局变量的构造顺序在翻译单元之间未定义,但您可以确保使用本地静态的顺序构建对象。这不是“糟糕的设计”。 – 2010-05-30 17:40:41

+0

它是设计模式的基础的事实并没有使它不坏设计。特别是因为,如上所述,它不能移植到多个线程。 – Puppy 2010-05-30 17:58:00

+0

我从来没有说过它是一个模式的一部分,使它成为好的设计。但这并不意味着它也不好。至于多线程,根据您的编译器,它是完全可移植的。由于任何类型的线程都是特定于编译器的,所以根本谈不上任何类型的线程本身是不可移植的,所以我没有看到调用这种东西不可移植的基础。 – 2010-05-30 18:47:01

0

如果您使用多个线程,则使用信号量,它的用途。