Utilice la volátil palabra clave para hacer alusión al compilador que el valor puede cambiar en cualquier momento.
volatile int myInteger;
Lo anterior garantizará que todo acceso a la variable será hacia y desde la memoria sin ningún tipo de optimizaciones específicas y como resultado todos los subprocesos que se ejecutan en el mismo procesador se "ver" los cambios en la variable con la misma semántica como el código lee.
Chris Jester-Young señaló que los problemas de coherencia a tal cambio de valor variable pueden surgir en un sistema multiprocesador.Esto es una consideración y depende de la plataforma.
En realidad, hay realmente dos consideraciones para pensar en relación con la plataforma. Son coherencia y atomicidad de las transacciones de memoria.
La atomicidad es en realidad una consideración tanto para las plataformas de procesador único como multiprocesador. El problema surge porque la variable es probablemente de varios bytes en la naturaleza y la pregunta es si un hilo podría ver una actualización parcial del valor o no. es decir: algunos bytes cambiados, cambio de contexto, valor no válido leído al interrumpir el hilo. Para una sola variable que está en el tamaño de la palabra de la máquina natural o más pequeño y naturalmente alineado no debería ser una preocupación. Específicamente, un tipo int siempre debe estar bien en este aspecto siempre que esté alineado, que debería ser el caso predeterminado para el compilador.
En relación con la coherencia, esta es una preocupación potencial en un sistema multiprocesador. La pregunta es si el sistema implementa la coherencia total del caché o no entre los procesadores. Si se implementa, esto generalmente se hace con el protocolo MESI en hardware. La pregunta no indicaba plataformas, pero tanto las plataformas Intel x86 como las plataformas PowerPC son coherentes entre los procesadores para regiones de datos de programas normalmente mapeados. Por lo tanto, este tipo de problema no debería ser una preocupación para los accesos de memoria de datos ordinarios entre subprocesos, incluso si hay múltiples procesadores.
El último problema relacionado con la atomicidad que surge es específico de la atomicidad de lectura-modificación-escritura. Es decir, cómo se garantiza que si se lee un valor actualizado en el valor y el escrito, que esto ocurra atómicamente, incluso en todos los procesadores si hay más de uno. Por lo tanto, para que esto funcione sin objetos de sincronización específicos, se requeriría que todos los subprocesos potenciales que acceden a la variable sean lectores ÚNICAMENTE pero se espera que solo un hilo pueda ser escritor al mismo tiempo. Si este no es el caso, entonces necesita un objeto de sincronización disponible para poder garantizar acciones atómicas en las acciones de lectura, modificación y escritura de la variable.
Esta es una buena información adicional a considerar además de los puntos que hice en mi respuesta aquí. –
"Si necesita y usa barreras de memoria, ya no debería necesitar volátiles" Um ... ¿aún no necesitaría volátiles para evitar que el compilador guarde en caché la variable en un registro para el bucle que lee el valor, por ejemplo? De la misma respuesta: "necesitas hacer que DataUpdated sea volátil; de lo contrario, el compilador puede leerlo sin problemas". No veo cómo una barrera de memoria ayuda con esto. –
Las barreras de memoria deben implementarse de todos modos con la ayuda del compilador. Si le pide al compilador que se asegure de que la CPU no puede ejecutar la carga/almacenamiento exactamente en este orden, entonces el compilador debe comenzar respetando el orden en sí. Entonces la barrera implica todo lo volátil, y más. – puetzk