thread safe practice lock concurrentbag best c# .net thread-safety

c# - safe - ¿Qué hace que los miembros de la instancia sean inseguros frente a los estáticos públicos?



thread safe list c# (5)

Así que todos hemos visto la notificación de subprocesos en MSDN para muchos objetos genéricos disponibles:

"Los miembros públicos estáticos (compartidos en Visual Basic) de este tipo son seguros para subprocesos. No se garantiza que ningún miembro de instancia sea seguro para subprocesos".

Mi pregunta es, ¿de qué se trata ser una variable de instancia frente a una estática pública que la hace insegura?


El problema con los métodos que no son seguros para subprocesos es el acceso simultáneo a recursos compartidos, como las variables de instancia. Si un método estático solo funciona con datos privados / locales, es inherentemente seguro para subprocesos. Sin embargo, no hay garantía de que los métodos estáticos hagan eso, esto debe hacerse explícitamente.

Por lo tanto, para que un método estático sea seguro para subprocesos, no puede acceder a los miembros estáticos sin usar la sincronización y debe copiar los datos que reciba como entrada antes de modificarlos.


Es el tema del estado. Lo que generalmente hace que los métodos sean inseguros para múltiples subprocesos es que no acceden al estado compartido de una manera segura para subprocesos. Los métodos estáticos en general no acceden al estado compartido y, por lo tanto, es menos probable que se encuentren con este problema. Todavía es posible tener condiciones de carrera en métodos estáticos / compartidos si tocan datos estáticos, pero en general los métodos estáticos no lo hacen.


Esto solo es cierto en general.

En general, los métodos estáticos son estáticos porque no dependen ni acceden a ningún dato definido por la instancia al que también pueda acceder otro subproceso. En general, las únicas variables que utilizan (un método estático) son las variables declaradas y vinculadas a la memoria estática de la clase en la que se implementa el método, no a la memoria asignada para el objeto (la instancia de la clase) creada para ese objeto. . Un método estático no hace ni puede hacer referencia o utilizar ninguna de estas variables. Si un método utiliza este tipo de variable de datos de instancia, vinculado a una instancia específica, no puede ser estático. Un método de instancia, por el contrario, accede a algún elemento de datos (propiedad o campo) de la instancia.

Si, otoh, un método estático accede a una propiedad o campo estático de la clase, es igualmente seguro para los subprocesos.

Hay cuatro condiciones necesarias para que una carrera sea posible.

  1. La primera condición es que hay ubicaciones de memoria que son accesibles desde más de un hilo. Normalmente, estas ubicaciones son variables globales / estáticas o se puede acceder a la memoria del montón desde variables globales / estáticas.
  2. La segunda condición es que hay una propiedad (a menudo llamada invariante), que está asociada con estas ubicaciones de memoria compartida que debe ser verdadera o válida para que el programa funcione correctamente. Normalmente, la propiedad debe mantenerse verdadera antes de que se produzca una actualización para que la actualización sea correcta.
  3. La tercera condición es que la propiedad invariable no se mantiene durante alguna parte de la actualización real. (Es transitoriamente inválido o falso durante alguna parte del procesamiento).
  4. La cuarta y última condición que debe ocurrir para que ocurra una carrera es que otro hilo acceda a la memoria mientras el invariante se rompe, lo que provoca un comportamiento incoherente o incorrecto.

Nada de lo incorporado hace que la estática sea más o menos diferente (con respecto a la seguridad de subprocesos) que la instancia, excepto:

  • los métodos estáticos a menudo son métodos "puramente funcionales" sin estado, lo que los hace automáticamente seguros para subprocesos
  • existe una clara expectativa de que los miembros estáticos estén seguros de subprocesos (ya que realmente no puede controlar lo que cada subproceso está haciendo al mismo tiempo), por lo que se espera que cualquier método estático que pueda poner en riesgo la seguridad de los subprocesos

Esto no es cierto para los métodos de ejemplo:

  • los métodos de instancia comúnmente acceden al estado en esa instancia
  • no hay expectativa de seguridad de subprocesos a menos que se haga explícito en la documentación

Por lo tanto, en general, se espera que la persona que llama administre la seguridad de subprocesos en instancias.

Hay excepciones en las que las instancias son seguras para subprocesos (generalmente para las cosas que están profundamente vinculadas a los subprocesos, como una cola de productores y consumidores), pero IMO cualquier miembro estático que no sea seguro para subprocesos es un error.


TLDR; "¿Significa esto que los métodos estáticos son intrínsecamente seguros para subprocesos? La respuesta es no. Las clases con la nota anterior tendrán métodos estáticos para subprocesos seguros porque los ingenieros de Microsoft escribieron el código de manera segura para los subprocesos, tal vez utilizando bloqueos u otros mecanismos de sincronización de subprocesos" (cita tomada de http://odetocode.com/Articles/314.aspx )

Mas detalle

¿Qué es? Nada, excepto el código escrito para esa clase en particular.

La declaración es una declaración que le indica que los programadores que escribieron la clase se han asegurado de que todos los miembros estáticos (métodos y propiedades) sean seguros para subprocesos (pero no lo han hecho para los miembros de la instancia).

Han asegurado que las estadísticas estén seguras de subprocesos porque, al ser estático, es muy probable que reciban llamadas de varios subprocesos, por lo que realizan el trabajo adicional necesario para asegurarse de que esto estará bien. A menudo, los métodos estáticos también son funciones sin estado, lo que significa que ya son generalmente seguros para subprocesos (no se necesita trabajo adicional).

En contraste, por ejemplo, los miembros de la declaración son simplemente diciendo que no han sido tan cuidadosos con ellos.

A menudo, las instancias serán creadas por un solo hilo y solo serán accedidas por ese hilo; Si nunca se accede a la instancia mediante varios subprocesos, la seguridad de los subprocesos no es un problema, por lo que los programadores no se molestaron en agregarla.

La declaración no es un reclamo sobre ninguna propiedad inherente de estática vs instancia; ambos pueden ser inseguros a menos que se ingrese un código específico para garantizar que múltiples subprocesos puedan acceder a ellos sin problemas (o si por su naturaleza ya son seguros para subprocesos, por ejemplo, una función sin estado).

Es simplemente una declaración de que los programadores que escribieron esas clases se han asegurado de que los miembros estáticos estén seguros, pero no lo han hecho, por ejemplo, los miembros.