2009-07-20 7 views
18

Lee y escribe en ciertos tipos primitivos en C# como bool y int son atómicos.¿Se lee y escribe en propiedades atómicas en C#?

(Véase la sección 5.5, "5.5 atomicidad de las referencias a variables", en la especificación del lenguaje C#.)

Pero ¿qué pasa con el acceso a dichas variables a través de las propiedades? ¿Es razonable suponer que también serán atómicos y seguros para la ejecución de subprocesos? P.ej. Es una lectura de MyProperty continuación atómica y flujos seguros ?:

public bool MyProperty { get { return _foo; } } 

Y qué acerca de las propiedades de auto-aplicado?

public bool MyProperty { get; } 
+0

he tenido la intención de hacer esta misma por un tiempo ... Sólo estoy adivinando, por lo que se lo ponga en una respuesta , pero no me sorprendería si las propiedades automáticas son atómicas. Cualquier otra cosa probablemente no es así. –

Respuesta

28

Debe distinguir entre "atomic" y "thread-safe" más de cerca. Como dices, las escrituras son atómicas para la mayoría de los tipos y referencias de valores incorporados.

Sin embargo, eso no significa que sean seguros para subprocesos. Simplemente significa que si los valores "A" y "B" están escritos, un hilo nunca verá algo intermedio. (Por ejemplo, un cambio de 1 a 4 nunca mostrará 5, o 2, o ningún valor distinto de 1 o 4.) Es no significa que un hilo verá el valor "B" tan pronto como se haya escrito en la variable. Para eso, necesita mirar el modelo de memoria en términos de volatilidad. Sin barreras de memoria, generalmente obtenidas a través de variables de bloqueo y/o volátiles, las escrituras en la memoria principal pueden retrasarse y las lecturas pueden avanzar, suponiendo efectivamente que el valor no ha cambiado desde la última lectura.

Si tenía un contador y le pidió su último valor, pero nunca recibió el último valor debido a la falta de barreras de memoria, no creo que pueda razonablemente llamarlo seguro para subprocesos aunque cada operación bien puede ser atómico.

Esto no tiene nada que ver con las propiedades, sin embargo, las propiedades son simplemente métodos con azúcar sintáctico a su alrededor. No hacen garantías adicionales al enhebrar. El modelo de memoria .NET 2.0 tiene tienen más garantías que el modelo ECMA, y es posible que ofrezca garantías en cuanto a la entrada y salida del método. Esas garantías deberían aplicarse también a las propiedades, aunque me pondría nervioso la interpretación de tales reglas: a veces puede ser muy difícil razonar sobre los modelos de memoria.

+0

Gracias. Supuse que "atómico" significaba atómico en todas partes, incluso a través de los hilos. Eso es lo que la palabra me sugirió. Enhebrar realmente está cargado de peligro. –

1

Si examina el código generado automáticamente, verá que las propiedades de auto-generadas son NO seguro para hilos - que son simples get/set a un campo generado. De hecho, sería demasiado golpe de rendimiento para hacerlo (especialmente cuando no es necesario).

Además, si está planeando acceder a los valores de int/bool de varios subprocesos, debe marcarlo (el campo) como volatile. Esto básicamente evita problemas de subprocesamiento múltiple relacionados con los registros de la CPU. (Esto es en Además para bloquear, no es una alternativa)

+8

Esto está mal. Está confundiendo la atomicatity de la memoria con la visibilidad entre los hilos. Se garantiza que todas las lecturas/escrituras de variables con un tamaño menor que el int nativo son atómicas. Consulte la sección 12.6.6 de la especificación de lenguaje CLI para obtener más detalles. – JaredPar

+0

Tienes razón, me refiero a hilo seguro (no atómico). Me sirve para responder tan temprano en la mañana;) –

+0

@Richard, Por la mañana a menudo me mantengo alejado de SO hasta que he terminado mi café por mi propia seguridad. O al menos mis representantes :) – JaredPar

0

Creo que no. Las propiedades son esencialmente solo métodos con un poco de azúcar sintáctico para facilitar su trabajo. Por lo tanto, de forma predeterminada, no son más seguras para subprocesos que una llamada a método normal (es decir, no es seguro para subprocesos).

2

No estoy del todo claro en cuanto a lo que está preguntando aquí. Parece que podría estar haciendo 1 de 2 preguntas

  1. ¿Está leído de _foo mientras llama a MyProperty atomic?
  2. ¿El valor de retorno de MyProperty está configurado atómicamente?

Para # 1 la respuesta es sí. Como indica la especificación del lenguaje C# (y CLI), se garantiza que las variables de lectura y escritura de ciertos tipos especificados serán atómicas. El tipo 'bool' es uno de esos tipos.

En cuanto al n. ° 2, el mejor lugar para buscar es la sección 12.6.6 de la especificación CLI. Afirma que

Un CLI conforme deberá garantizar que el acceso de lectura a alineado correctamente las posiciones de memoria no más grandes que el tamaño de la palabra nativa (el tamaño de tipo int nativo) es atómica

Teniendo en cuenta el uso el valor de retorno de MyProperty debe leer o escribir el valor, es seguro asumir que está configurado atómicamente.

1

La atomicidad solo significa que si hay más de un subproceso escribiendo en una variable, su valor no se corromperá (por ejemplo, si ocupa dos bytes, nunca obtendrá el byte alto del subproceso y el byte bajo del subproceso dos). Lo hace no significa que la variable es segura para subprocesos. Todavía puede obtener los problemas de subprocesos habituales de un subproceso que no ve otros cambios, etc.

Para la seguridad del subproceso, debe usar el bloqueo (o volátil, pero esto es más difícil de entender). No hay nada especial acerca de las propiedades: también deben estar explícitamente seguras para subprocesos.

0

Usted puede poner cualquier cosa en una propiedad, por ejemplo

Public Property foo() As Boolean 
     Get 
      goToLunch() 
      barbecueRibs() 
      return m_foo 
     End Get 
     Set(ByVal value As Boolean) 
      takeANap() 
      accessDatabase() 
      messUpOtherVariables() 
      m_foo = value 
     End Set 
    End Property 
Cuestiones relacionadas