2011-01-06 18 views
16

Gli oggetti e le variabili creati in una funzione membro statica non sono considerati "locali" come farebbero in una funzione membro, in modo che ora possano essere condivisi tra più thread, giusto?funzioni membro statiche e sicurezza thread

Considerando che se si dispone di una funzione membro che crea un oggetto, questo sarebbe locale al thread e quindi non è condiviso.

Sono corretto nel dire questo?

+0

possibile duplicato di [funzione membro statica e sicurezza thread] (http://stackoverflow.com/questions/4509850/static-member-function-and-thread-safety) – Suma

+5

Tony, perché, sulla terra, sei chiedendo di nuovo la stessa domanda? – Suma

+0

@Suma Ho votato per chiudere la mia domanda, ho dimenticato di averlo già chiesto ... –

risposta

19

No, non sei corretto.

Gli oggetti creati con una funzione statica non sono condivisi da e questo vale anche per le normali funzioni.

Gli oggetti possono essere condivisi anche se sono dichiarati statici stessi e non dipende se la funzione è statica o meno.

void myFunc() 
{ 
    static MyObject o; 
    o.CallMethod(); // here o is shared by all threads calling myFunc 
} 

Quando un oggetto viene dichiarato statico, è come se l'oggetto è una variabile globale, ma visibile solo nell'ambito della funzione che viene dichiarata in.

+0

Esistono almeno 3 modi per creare un oggetto. X x; X * x = nuova X; X * x = new (mem) X. –

+0

@Maxim e sarebbero condivisi ** solo ** in questo modo: 'statico X x; statico X * x = nuovo X; 'Cosa significa/implica il tuo commento? è vago !? –

+0

Questo: X * x = nuovo (mem) X; può creare un oggetto condiviso tra thread o processi. E può essere fatto da una funzione membro statica, che dimostra che la tua affermazione "Oggetti creati in una funzione statica non sono condivisi" è sbagliata. –

1

Non importa se una funzione è statica o meno (metodo di classe). Solo le variabili automatiche possono essere viste come locale in una funzione. Se hai l'indirizzo di quei dati, puoi accedervi.

È possibile utilizzare ad es. thread-local storage per assegnare l'output a un contesto thread dedicato.

3

No, non sei corretto. E sì, il C++ fa un uso eccessivo della parola "statico".

Una variabile membro di classe statico è ovviamente globale con la classe che funge da ambito spazio dei nomi e con alcune differenze di privilegi di accesso se è privata o protetta (è possibile accedervi solo dalla classe).

Tuttavia, una funzione membro di classe statica è proprio come una normale funzione libera (non membro della classe) e ha le sue variabili locali ogni volta che viene chiamata.

L'unica vera differenza tra una funzione membro di classe statica e una funzione libera normale, a parte la convenzione di denominazione, è che ha accesso ai membri privati ​​di una classe (e richiede un'istanza esterna di una classe).

Inoltre, una funzione di membro di classe statico può essere chiamata da un modello con un parametro di modello variabile, che richiama quello che viene comunemente chiamato "polimorfismo in fase di compilazione" ed è comunemente utilizzato nella meta-programmazione.

Una variabile "locale" statica in qualsiasi funzione è una singola istanza, d'altra parte, è anche un po 'come globale ed è sensibile ai problemi di conflitto di thread poiché due thread che chiamano la funzione accedono alla stessa istanza.

39

Considerate questa classe

class CData 
{ 
public: 
    static void func() 
    { 
     int a; 
     static int b; 
    } 

    int c; 
    static int d; 
}; 

int main() 
{ 
    CData::func(); 
} 

Ora variabile a è locale per ogni chiamata di func(). Se due thread chiamano allo stesso tempo func(), ottengono versioni differenti di a.

b è un locale statico.Il valore persiste tra diverse chiamate di func(). Se due thread chiamano allo stesso tempo func(), accedono alla stessa versione di b in modo che potrebbero dover eseguire la sincronizzazione.

c è una variabile di istanza; è collegato a una particolare istanziazione di CData. func() non può accedere a c, tranne con un trucco che mostrerò di seguito.

d è una variabile statica. Esiste un'istanza di d condivisa tra tutti gli usi dei CD di classe, pertanto potrebbe essere necessaria la sincronizzazione. Può essere facilmente utilizzato dalla funzione statica func().

Il trucco utilizzato per accedere ai dati di istanza da una funzione statica consiste nel passare un oggetto valido nella funzione.

ad es.

class CData 
{ 
public: 
    static void func(CData *p) 
    { 
     int a; 
     static int b; 

     b = p->c; 
    } 

    int c; 
    static int d; 
}; 

int main() 
{ 
    CData data; 
    CData::func(&data); 
} 

Spero che questo aiuti.

+4

Bella spiegazione amico! – Meysam

+2

questa è di gran lunga la migliore spiegazione che ho visto. Grazie. Mi ha aiutato molto! – AnyOneElse

+1

nitido e chiaro! La migliore spiegazione mi è arrivata, al punto, grazie mille! – ADJ