2011-01-06 18 views
16

Los objetos y las variables creados en una función miembro estática no se consideran 'locales' como lo harían en una función miembro, por lo que ahora se pueden compartir entre varios subprocesos ¿no?funciones miembro estáticas y seguridad de subprocesos

Considerando que si tiene una función de miembro que crea algún objeto, esto sería local para el hilo y, por lo tanto, no es compartido.

¿Estoy en lo correcto al decir esto?

+0

posible duplicado de [función de miembro estático y seguridad de hilos] (http://stackoverflow.com/questions/4509850/static-member-function-and-thread-safety) – Suma

+5

Tony, ¿por qué estás en la tierra? haciendo la misma pregunta de nuevo? – Suma

+0

@Suma He votado para cerrar mi propia pregunta, olvidé que ya lo había preguntado ... –

Respuesta

19

No, no eres correcto.

Los objetos creados en una función estática no son compartidos, y este es también el caso de las funciones normales.

Aunque los objetos se pueden compartir si se declaran estáticos y no depende si la función es estática o no.

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

Cuando un objeto se declara estático, es como si el objeto era una variable global, pero pueden ser vistos en el ámbito de la función que se declara en.

+0

Existen al menos 3 formas de crear un objeto. X x; X * x = nueva X; X * x = new (mem) X. –

+0

@Maxim y se compartirían ** solo ** de esta manera: 'static X x; static X * x = new X; '¿Qué significa o implica su comentario? es vago! –

+0

Esto: X * x = nuevo (mem) X; puede crear un objeto compartido entre hilos o procesos. Y se puede hacer desde una función miembro estática, lo que prueba que su declaración "Los objetos creados en una función estática no se comparten" es incorrecta. –

1

No importa si una función es estática o no (método de clase). Solo las variables automáticas se pueden ver como local en una función. Si tiene la dirección de esos datos, puede acceder a ellos.

Puede usar, p. thread-local storage para asignar su salida a un contexto de subproceso dedicado.

3

No, no estás en lo cierto. Y sí, C++ usa mucho la palabra "estática".

Una variable de miembro de clase estática es, por supuesto, global con la clase actuando como un ámbito de espacio de nombres y con algunas diferencias de privilegios de acceso si es privada o protegida (solo puede accederse por la clase).

Sin embargo, una función de miembro de clase estática es como una función libre normal (no miembro de clase) y tiene sus propias variables locales cada vez que se llama.

La única diferencia real entre una función de miembro de clase estática y una función libre regular, además de su convención de nomenclatura, es que tiene acceso a miembros privados de una clase (y necesita una "instancia" externa de uno).

Además, se puede llamar a una función de miembro de clase estática desde una plantilla con un parámetro de plantilla variable, invocando lo que comúnmente se llama "polimorfismo en tiempo de compilación" y se usa comúnmente en metaprogramación.

Una variable "local" estática en cualquier función es una instancia única, por otro lado, también es un poco global y es sensible a problemas de contención de hilos cuando dos hilos que llaman a la función acceden a la misma instancia.

39

considerar esta clase

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

    int c; 
    static int d; 
}; 

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

Ahora variables a es local a cada llamada de func(). Si dos hilos llaman al func() al mismo tiempo, obtienen diferentes versiones de a.

b es un local estático.El valor persiste entre diferentes llamadas de func(). Si dos hilos llaman al func() al mismo tiempo, tienen acceso a la misma versión de b, por lo que es posible que necesiten hacer una sincronización.

c es una variable de instancia; está adjunto a una instancia particular de CData. func() no puede acceder a c, excepto con un truco que mostraré a continuación.

d es una variable estática. Hay una instancia de d compartida entre todos los usos de la clase CData, por lo que la sincronización puede ser necesaria. Se puede usar fácilmente desde la función estática func().

El truco utilizado para acceder a los datos de instancia desde una función estática es pasar un objeto válido a la función.

p. Ej.

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); 
} 

Espero que ayude.

+4

¡Buena explicación, amigo! – Meysam

+2

esta es de lejos la mejor explicación que he visto. Gracias. ¡Me ayudo mucho! – AnyOneElse

+1

nítido y claro! La mejor explicación que encontré, al grano, ¡muchas gracias! – ADJ

Cuestiones relacionadas