2010-04-08 22 views
5

¿Es seguro que un hilo LEA una variable establecida por un evento Delphi VCL?¿Pueden los hilos leer de forma segura las variables establecidas por los eventos VCL?

Cuando un usuario hace clic en un VCL TCheckbox, el hilo principal establece un valor booleano en el estado Comprobado de la casilla de verificación.

CheckboxState := CheckBox1.Checked; 

En cualquier momento, un hilo lee esa variable

if CheckBoxState then ... 

No importa si el hilo "no alcanza" un cambio en el valor booleano, porque el hilo comprueba la variable en un bucle como hace otras cosas. Por lo tanto, verá el cambio de estado con el tiempo ...

¿Esto es seguro? ¿O necesito un código especial? Está rodeando la lectura y escritura de la variable (en el hilo y en el hilo principal, respectivamente) con llamadas de código críticas necesarias y suficientes?

Como dije, no importa si el hilo obtiene el valor "incorrecto", pero sigo pensando que podría haber un problema de bajo nivel si un hilo intenta leer una variable mientras el hilo principal está en a la mitad de escribirlo, o viceversa.

Mi pregunta es similar a esta: Cross thread reading of a variable who's value is not considered important.

(También en relación con mi anterior pregunta: Using EnterCriticalSection in Thread to update VCL label)

+0

Tenga en cuenta que los eventos de VCL no son nada especiales. Su pregunta se aplica igualmente bien al acceso a la variable desde * cualquier * tipo de función en * cualquier * dos hilos. –

Respuesta

6

Esto es seguro, por tres razones:

  • sólo un hilo escribe en la variable.

  • La variable tiene solo un byte, por lo que no hay forma de que lea un valor incoherente. Se leerá como True o como False. No puede haber problemas de alineación con los valores de Delphi boolean.

  • El compilador Delphi no comprueba exhaustivamente si una variable está realmente escrita y no "optimiza" ningún código si no es así. Las variables no locales siempre se leerán, no es necesario el especificador volatile.

Dicho esto, si usted está realmente seguro acerca de esto usted podría utilizar un valor integer en lugar del booleano, y utiliza la función InterlockedExchange() escribir en la variable. Esto es excesivo aquí, pero es una buena técnica para conocer, ya que para valores de una sola máquina de tamaño de palabra puede eliminar la necesidad de bloqueos.

También puede reemplazar boolean por una primitiva de sincronización adecuada, como un evento, y tener el bloque de hilos en eso - esto le ayudaría a eliminar los bucles ocupados en la secuencia.

1

Para el ejemplo que das, será seguro. Técnicamente, el problema principal es en los casos en los que su variable supera el tamaño de una palabra de máquina y, por lo tanto, es posible que la palabra alta y la palabra larga no se sincronicen. Sin embargo, para valores pequeños, esto no es un problema.

Si cree que es un problema potencial, por ejemplo, usando un puntero, entonces lo que se debe utilizar es una TCriticalSection para controlar la lectura y escritura del elemento. Esto es lo suficientemente rápido para todas las situaciones prácticas y garantiza que esté 100% seguro.

3

En su caso (propiedad controlada) una operación de lectura es atómica, por lo que es segura. Eso es lo mismo que con la propiedad TThread.Terminated; las operaciones simples de lectura y escritura para los bytes, palabras y palabras dobles correctamente alineados son atómicos. Puede comprobar intel documentation para más información:

Capítulo 8 - Gestión de procesador múltiple

8.1.1 garantizado operaciones atómicas

El procesador Intel486 (y más nuevos procesadores desde) garantiza que la siguiente operaciones básicas de la memoria siempre se lleva a cabo de forma atómica:

  • de lectura o escritura de un byte
  • la escritura o lectura palabra alineado en un 16-bit límite
  • leer o escribir una palabra doble alineados en un límite de 32 bits

El procesador Pentium (y más nuevos procesadores desde) garantiza que siempre se realizarán los siguientes operaciones de memoria adicionales a cabo atómicamente:

  • leer o escribir una palabra cuádruple alineados en un límite de 64 bits
  • 16 bits accede a las posiciones de memoria sin almacenar en caché que se ajustan dentro de un bus de datos de 32 bits
Cuestiones relacionadas