2010-03-03 19 views
12

Heute sind wir über ein Problem in Bezug auf statische Elementfunktionen in einer Multithread-Umgebung gekommen. Die Frage, die wir uns gestellt haben und die keine befriedigende Antwort gefunden hat, ist: sind lokale Variablen von statischen Elementfunktionen statisch?lokale Variablen von statischen Elementfunktionen

// header 

class A 
{ 
    static int test(); 
} 

// implementation 
int A::test() 
{ 
    int a = rand(); 
    int b = rand(); 
    int c = a + b; 

    return c; 
} 

Angenommen, Sie haben zwei Threads, die beide A :: test() aufrufen. Ist es möglich, dass, während Thread 1 verarbeitet c = a + b Thread 2 tritt test() und ändert den Wert a durch Zuweisen der neuen Rückgabewert von rand() oder mit anderen Worten operieren beide Threads eine der einige Speicherplätze für a, b und c ?

Antwort

16

Nein. Die Stack-Frames sind für den Aufruf der Funktion durch jeden Thread unabhängig und jeder erhält seine eigenen Locals. (Sie müssen vorsichtig sein, wenn Sie auf tatsächlich freigegebene Daten zugreifen, z. B. statische Member in der Klasse.)

1

Die Speicherklasse von a, b und c sind (implizit) automatisch, was normalerweise auf dem Aufruf-Stack bedeutet. Sie "erben" statische Speicherklasse nicht von der Methodensignatur (was eine andere Bedeutung von statisch ist (yay für stark überladene Schlüsselwörter!)).

2

Wenn nicht explizit als statisch deklariert, nein sind sie nicht. Sie sind auf einem Stapel und jeder Thread hat einen separaten Stapel.

0

Nein, a, b und c sind nicht statisch.

Hier ist ein Beispiel, das diese veranschaulicht:

class Val 
{ 
public: 
    Val() { cout << "Val" << this << endl; } 
    ~Val() { cout << "~Val" << this << endl; } 
    int n_; 
}; 

class A 
{ 
public: 
    static int test() 
    { 
     Val a; 
     a.n_ = rand(); 
     Val b; 
     b.n_ = rand(); 
     Val c; 
     c.n_ = a.n_ + b.n_; 
     return c.n_; 
    } 
}; 

int main() 
{ 
    srand(time(0)); 
    for(int i = 0; i < 5; ++i) 
    { 
     cout << "Test = " << A::test() << endl; 
    } 

    return 0; 

}