En otras palabras, ¿puedo hacer algo con una variable volátil que tampoco podría ser resuelta con una variable normal y la clase Interbloqueada?¿Hay alguna ventaja de usar palabra clave volátil en contraste para usar la clase Interbloqueado?
Respuesta
EDIT: pregunta reescrito en gran medida
Para responder a esta pregunta, he buceado un poco más en el asunto y descubrí algunas cosas sobre volatile
y Interlocked
que yo no era consciente. Vamos a aclarar eso, no sólo para mí, pero para esta discusión y otras personas que lean sobre esto:
volatile
de lectura/escritura se supone que son inmunes a la reordenación. Esto solo significa leer y escribir, hace no significa cualquier otra acción;- la volatilidad no es forzado en la CPU, es decir, a nivel de hardware (x86 utiliza adquirir y liberar vallas en cualquier de lectura/escritura). Previene optimizaciones de compilador o CLR;
Interlocked
usa instrucciones de ensamblaje atómicas para CompareExchange (cmpxchg
), Incremento (inc
) etc;Interlocked
usa veces un candado: a hardware lock on multi processor systems; en los sistemas de procesador único, no hay bloqueo de hardware;Interlocked
es diferente devolatile
en que utiliza una valla completa, donde volatil utiliza una media valla.- A read following a write can be reordered cuando usa
volatile
. No puede suceder conInterlocked
.VolatileRead
yVolatileWrite
tienen el mismo problema de reordenación que `volátil (enlace gracias a Brian Gideon).
Ahora que tenemos las reglas, podemos definir una respuesta a su pregunta:
- Técnicamente: sí, hay cosas que puede hacer con
volatile
que no se puede hacer conInterlocked
:- sintaxis: no se puede escribir
a = b
dondea
ob
es volátil, pero esto es obvia; - se puede leer un valor diferente después de escribir a una variable volátil debido a la reordenación. No puede hacer esto con
Interlocked
. En otras palabras: puede ser menos seguro convolatile
, entonces puedes estar conInterlocked
. - Rendimiento:
volatile
es más rápido queInterlocked
.
- sintaxis: no se puede escribir
vista semántico: no, porque
Interlocked
simplemente proporciona un superconjunto de las operaciones y es más seguro de usar, ya que se aplica la esgrima completo. No se puede hacer nada convolatile
que no se puede ver conInterlocked
y se puede hacer mucho conInterlocked
que no se puede ver con volátil:static volatile int x = 0; x++; // non-atomic static int y = 0; Interlocked.Increment(y); // atomic
Alcance: sí, se declara una variable
volatile
hace que sea volátil para cada acceso individual. Es imposible forzar este comportamiento de otra manera, por lo tanto,volatile
no se puede reemplazar porInterlocked
. Esto es necesario en escenarios donde otras bibliotecas, interfaces o hardware pueden acceder a su variable y actualizarla en cualquier momento, o necesitan la versión más reciente.
Si me preguntan, este último es la verdadera necesidad real para volatile
y puede hacer que sea ideal donde los dos procesos comparten memoria y necesitan leer o escribir sin bloquear. La declaración de una variable como volatile
es mucho más seguro en este contexto, a continuación, obligando a todos los programadores utilizar Interlocked
(que no se puede forzar por el compilador).
EDIT: La siguiente cita fue parte de mi respuesta original, lo dejaré en ;-)
Una cita de la el C# lenguaje de programación estándar:
Para campos no volátiles, optimización técnicas que consideran que las instrucciones de reorden pueden dar como resultado inesperados y resultados impredecibles i n programas multiproceso que acceden a los campos sin sincronización, como que proporciona instrucción de bloqueo. Estos optimizationscan ser realizadas por el compilador, el sistema de ejecución, o por el hardware.Para los campos de volátiles, tales optimizaciones de reordenamiento son restringido:
Una lectura de un campo volátil se llama un volátil leer. Un volátil leer ha:. Adquirir semántica ", es decir, que se garantiza que se produzca antes de cualquier referencias a la memoria que se producen después en la secuencia de instrucciones
que se llama una escritura de un campo volátil una . escritura volátil Un escritura volátil tiene "liberar semántica."; es decir, se garantiza a ocurrir después de cualquier referencia a la memoria antes de la instrucción de escritura en la secuencia de instrucciones
Actualización: pregunta reescrito en gran medida, corregida mi respuesta original y añade un "verdadero" respuesta
La clase Interbloqueada no tiene que hacer mucho con un bloqueo y tiene (a diferencia de la cerradura) no mucha sobrecarga asignada con él - en la mayoría de las CPU los métodos Enclavados se implementan como una sola instrucción. – codymanix
Tiene razón, gracias por señalarlo. Al examinar 'CompareExchange' (pensando que no sería atómico), SSCLI (CLI de fuente compartida) muestra que finalmente se traduce en la instrucción de ensamblaje' cmpxchg' en procesadores x86, y que la instrucción es, como cualquier otra cosa en 'Interlocked', de hecho atómico. – Abel
Que, y otras correcciones, además de reescribir están ahora en la respuesta :) – Abel
Sí, puede ver el valor directamente.
Mientras SÓLO uses la clase Interbloqueada para acceder a la variable, entonces no hay diferencia. Lo que volátil hace es le dice al compilador que la variable es especial y al optimizarla no debe asumir que el valor no ha cambiado.
Toma este bucle:
bool done = false;
...
while(!done)
{
... do stuff which the compiler can prove doesn't touch done...
}
Si establece done
a true
en otro hilo que se puede esperar del bucle para salir. Sin embargo, si está hecho no está marcado como volatile
, entonces el compilador tiene la opción de darse cuenta de que el código del bucle nunca puede cambiar done
y puede optimizar la comparación para la salida.
Esta es una de las cosas difíciles de la programación multiproceso: muchas de las situaciones que son problemas solo surgen en ciertas situaciones.
Puede hacer lo mismo con Interlocked.Read(). – codymanix
Tu descripción de volátil es levemente incorrecta. Usted describe C++ volátil (no es bueno para multihilo). C# (y Java) volátil hacen que el compilador inserte las operaciones de sincronización cuando accede a la variable. Debido a las sincronizaciones, se ve obligado a volver a leer la variable cada vez, lo que tiene un efecto similar al volátil de C++. –
Este es un tema bastante complejo. Encuentro el writeup de Joseph Albahari como una de las fuentes más definitivas y precisas para conceptos de subprocesamiento múltiple en .NET Framework que podría ayudar a responder su pregunta.
Pero, para resumir rápidamente, hay mucha superposición entre la palabra clave volatile
y la clase Interlocked
en cuanto a cómo se pueden usar. Y, por supuesto, ambos van mucho más allá de lo que puedes hacer con una variable normal.
¡Artículo muy bueno! Tomará un tiempo leerlo y mucho más tiempo para comprenderlo por completo – codymanix
No intentaré ser una autoridad en este tema, pero le recomendaría que echara un vistazo al this article del famoso Jon Skeet.
También eche un vistazo a la parte final de this answer que detalla para qué se debe usar volatile
.
El artículo de Skeet es bueno, pero solo abarca los conceptos básicos. Sé para qué sirve la volatilidad, pero la pregunta era si hay alguna situación en la que no puedas reemplazar la volatilidad con un método interconectado. – codymanix
Sí, puede obtener cierto rendimiento utilizando una variable volátil en lugar de un bloqueo.
La cerradura es una barrera de memoria completa que puede darle las mismas características de una variable volátil y muchas otras. Como ya se ha dicho, volátil solo asegura que en escenarios de subprocesos múltiples si una CPU cambia un valor en su línea de caché, las otras CPU ven el valor inmediatamente pero no aseguran ninguna semántica de bloqueo en absoluto.
Lo que pasa es que el bloqueo es mucho más potente que el volátil y debes usar volátiles cuando puedas para evitar bloqueos innecesarios.
No estaba hablando de la declaración de bloqueo, sino de la clase Interbloqueada, pero sí lo que dijiste es cierto – codymanix
- 1. ¿Cuándo se debe usar la palabra clave volátil en C#?
- 2. ¿Cómo puedo usar correctamente la palabra clave volátil en Java?
- 3. ¿Hay alguna ventaja al usar selectores muy específicos en CSS?
- 4. ¿Hay alguna ventaja de usar null primero en PHP?
- 5. ¿Puedo usar la palabra clave `abstracta` en la clase C++
- 6. ¿Dónde usar volátil?
- 7. Palabra clave volátil en Java - Clarificación
- 8. Pregunta sobre la palabra clave volátil
- 9. ¿Hay alguna manera de usar la palabra "tipo" como nombre de variable en Scala?
- 10. ¿Cuándo NO DE USAR esta palabra clave?
- 11. ¿Cuándo debería usar la palabra clave "self"?
- 12. Ilustrando el uso de la palabra clave volátil en C#
- 13. ¿Hay alguna razón para usar clases en Python si solo hay una clase en el programa?
- 14. ¿Hay alguna palabra clave en Java que sea similar a la palabra clave 'AS' de C#
- 15. C++ const palabra clave: ¿usar liberalmente?
- 16. ¿Hay alguna razón para usar Object.create() o new en JavaScript?
- 17. usando la palabra clave volátil en java4 y java5
- 18. ¿Cuándo utiliza exactamente la palabra clave volátil en Java?
- 19. ¿Cuál es el uso de la palabra clave volátil?
- 20. ¿Por qué debería usar la palabra clave "using" para acceder a mi método de clase base?
- 21. Cuándo usar volátil vs sincronización en multihilo en java?
- 22. ¿Cómo uso programáticamente la palabra clave "usar" en C#?
- 23. ¿Cuándo debería usar la palabra clave "strictfp" en java?
- 24. ¿Cuándo debería usar la palabra clave "this" en C++?
- 25. ¿Hay alguna razón para usar esto->
- 26. ¿Cómo usar la palabra clave 'referencias' en MySQL?
- 27. ¿Hay alguna razón para usar System.Uri?
- 28. ¿Hay alguna ventaja de usar '<< 1' en lugar de '* 2'?
- 29. ¿Cuándo debemos usar la palabra clave extern alias en C#?
- 30. ¿Cuándo necesitaría usar la palabra clave stackalloc en C#?
Sé para qué sirve el volátil. La pregunta es si hay alguna situación en la que no pueda reemplazar la volatilidad con un método interconectado. – codymanix