2009-03-25 18 views
6

Si tiene dos subprocesos que invocan una función estática en el mismo momento, ¿existe un riesgo de concurrencia? Y si esa función usa un miembro estático de la clase, ¿hay incluso un problema mayor?Concurrencia de función estática ASP.NET

  • ¿Las dos llamadas están separadas entre sí? (la función es similar a la de los dos hilos?)
  • ¿Están en cola automáticamente?

Por ejemplo, en el siguiente ejemplo, ¿hay algún riesgo?

private static int a = 5; 

public static int Sum() 
{ 
    int b = 4; 
    a = 9; 
    int c = a + b; 
    return c; 
} 

Y el siguiente ejemplo, ¿hay algún riesgo?

public static int Sum2() 
{ 
    int a = 5; 
    int b = 4; 
    int c = a + b; 
    return c; 
} 

Actualización: Y de hecho, si ambas funciones están en la misma clase, ¿cuál es el riesgo, entonces?

THX, Lieven Cardoen

Respuesta

10

Sí, existe el riesgo de concurrencia cuando se modifica una variable estática en los métodos estáticos.

Las funciones estáticas mismas tienen distintos conjuntos de variables locales, pero se comparten las variables estáticas.

En sus muestras específicas no está expuesto, pero eso es solo porque está usando constantes (y les asigna los mismos valores). Cambia ligeramente la muestra del código y estarás expuesto.

Editar:

Si llama tanto Sum1() y SUM2() de diferentes hilos que está en problemas, no hay manera de garantizar el valor de ayb en esta declaración: int c = a + b;

private static int a = 5; 

public static int Sum1() 
{ 
    int b = 4; 
    a = 9; 
    int c = a + b; 
    return c; 
} 

public static int Sum2() 
{ 
    int b = 4; 
    int c = a + b; 
    return c; 
} 

También puede conseguir problemas de concurrencia con múltiples invocaciones de un único método como este:

public static int Sum3(int currentA) 
{ 
    a = currentA; 
    int b = 4; 
    int c = a + b; 
    int d = a * b; // a may have changed here 
    return c + d; 
} 

El problema aquí es que el valor de una puede cambiar a mediados de método debido a otra invocaciones cambiándolo.

+0

me cambió primer ejemplo. ¿Ahora probablemente ya no es seguro para subprocesos? –

+0

¿Hay buenas referencias, libros, enlaces sobre este tema y cómo puede enfrentar estas situaciones? –

+0

http://www.amazon.com/Concurrent-Programming-Java-TM-Principles/dp/0201310090/ref=pd_bbs_sr_3?ie=UTF8&s=books&qid=1237967873&sr=8-3 debería servirle bien – krosenvold

1

En sus dos ejemplos, no hay problemas de seguridad de subprocesos porque cada llamada a la función tendrá su propia copia de las variables locales en la pila, y en su primer ejemplo con 'a' como variable estática, nunca cambie 'a', entonces no hay problema.

Si cambia el valor en 'a' en su primer ejemplo, tendrá un posible problema de concurrencia.

+0

Es cierto que no noté que la variable A no se modificó, por lo que todo está bien con el código que podemos ver. Potencialmente podría modificarse fuera del código visible –

+0

Cambiado. Lo siento. El primer ejemplo no fue tan bueno. –

1

Si el alcance de las variables está contenida dentro de la función estática, entonces no hay riesgo, pero las variables fuera del ámbito de la función (estática/compartida) suponen sin duda un riesgo de concurrencia

3

Sí, hay un riesgo. Es por eso que verá en MSDN doc, a menudo dirá "Esta clase es segura para los miembros estáticos" (o algo así).Significa que cuando MS escribió el código, utilizaron intencionalmente primitivas de sincronización para hacer que los miembros estáticos fueran seguros para el hilo. Esto es común cuando se escriben bibliotecas y marcos, porque es más fácil hacer que los miembros estáticos sean seguros en cuanto a los hilos que los miembros de la instancia, porque no se sabe lo que el usuario de la biblioteca querrá hacer con las instancias. Si hacían que los miembros de la instancia fueran seguros para muchas de las clases de la biblioteca, te pondrían demasiadas restricciones ... tan a menudo te dejan manejarlo.

Por lo tanto, también necesita hacer que sus miembros estáticos sean seguros (o documentan que no lo son).

Por cierto, los constructores estáticos son seguros para la rosca en cierto sentido. El CLR se asegurará de que se invoquen solo una vez y evitará que 2 subprocesos entren en un constructor estático.

EDITAR: Marc señaló en los comentarios un caso de borde en el que los constructores estáticos no son seguros para la rosca. Si usa el reflejo para llamar explícitamente a un constructor estático, aparentemente puede llamarlo más de una vez. Así que reviso la declaración de la siguiente manera: siempre y cuando confíe en el CLR para decidir cuándo llamar a su constructor estático, entonces el CLR evitará que se llame más de una vez, y también evitará que se llame al ctor estático. re-entrante.

+0

En realidad, no * no * garantiza * esto: puede invocar el inicializador de tipo a través de la reflexión trivial, en cuyo caso puede llamarlo varias veces a la vez. –

+0

Ah, interesante. Nunca pensé en eso. Buen punto.Sin embargo, siempre que evite llamarlo explícitamente a través de la reflexión, puede confiar en el CLR para hacerlo seguro. Eso es útil a veces. –

3

Consulte here para una discusión sobre las variables locales. antes de editar ninguno de los métodos anteriores ellos mismos presentaron un riesgo de concurrencia; las variables locales son todas independientes por llamada; el estado compartido (static int a) es visible para varios subprocesos, pero no lo muta, y solo lo lee una vez.

Si hizo algo como:

if(a > 5) { 
    Console.WriteLine(a + " is greater than 5"); 
} // could write "1 is greater than 5" 

sería (en teoría) no ser seguro, ya que el valor de una podría ser cambiado por otro hilo - que normalmente ya sea sincronizar el acceso (a través de lock etc), o tomar una instantánea:

int tmp = a; 
if(tmp > 5) { 
    Console.WriteLine(tmp + " is greater than 5"); 
} 

Si está editando el valor, que casi seguro que requieren sincronización.

+0

Thx. Perdón por la edición. –

1

Los métodos estáticos en OO no difieren de las funciones "just" en la programación de procedimientos. A menos que almacene algún estado dentro de la variable estática, no hay ningún riesgo.

Cuestiones relacionadas