2010-05-30 18 views
0

Je suis curieux de savoir le code suivant:Un objet statique dans une fonction introduit-il une condition de concurrence potentielle?

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; 
    [...] 
} 

est-il une condition de course possible dans le code ci-dessus? Plus précisément, le compilateur est-il susceptible de générer du code équivalent à ce qui suit, «en coulisses»?

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

... dans ce cas, si deux fils devaient appeler MyFunction() presque-simultanément, puis _myArray pourrait obtenir attribué deux fois, ce qui provoque une fuite de mémoire?

Ou est-ce géré correctement en quelque sorte?

+1

Beaucoup de dupes, y compris http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-ac-function –

+1

Ceci est probablement aussi pertinent: http://stackoverflow.com/questions/1661529/is-meyers-implementation-of-singleton-pattern-thread-safe –

Répondre

1

Il y a absolument une condition de concurrence possible ici. Qu'il y en ait une en réalité ou non, ce n'est pas bien défini. Vous ne devez pas utiliser un tel code dans des scénarios à thread unique, car la conception est mauvaise, mais cela peut être la mort de votre application multithread. Tout ce qui est statique const comme ça devrait probablement aller dans un espace de nom pratique, et être alloué au début de l'application.

+0

-1 pour cela. Mettre de la statique dans les fonctions est la base du singleton en C++, et parfois vous ne voulez pas payer le temps supplémentaire que chaque programme exécute pour construire un global. De plus, l'ordre de construction pour les globales n'est pas défini entre les unités de traduction, tandis que vous pouvez vous assurer que les objets sont construits dans le bon ordre en utilisant des statistiques locales. Ce n'est pas "mauvais design". –

+0

Le fait que ce soit la base d'un motif de conception ne rend pas le design pas mal. Surtout que, comme indiqué, il n'est pas portable à plusieurs threads. – Puppy

+0

Je n'ai jamais dit que la place faisait partie d'un motif qui en faisait un bon design. Mais cela ne veut pas dire que c'est mauvais non plus. Comme pour plusieurs threads, il est parfaitement portable selon votre compilateur. Comme tout type de thread est spécifique au compilateur, parler de n'importe quel type de thread est intrinsèquement non-portable, donc je ne vois pas de raison d'appeler une telle chose non-portable. –

0

Utilisez un sémaphore si vous utilisez plusieurs threads, c'est à ça qu'ils servent.