Hace poco leí sobre las barreras de memoria y el problema de la reordenación y ahora tengo algo de confusión al respecto.Barrier de memoria por instrucción de bloqueo
cuenta la situación siguiente:
private object _object1 = null;
private object _object2 = null;
private bool _usingObject1 = false;
private object MyObject
{
get
{
if (_usingObject1)
{
return _object1;
}
else
{
return _object2;
}
}
set
{
if (_usingObject1)
{
_object1 = value;
}
else
{
_object2 = value;
}
}
}
private void Update()
{
_usingMethod1 = true;
SomeProperty = FooMethod();
//..
_usingMethod1 = false;
}
En
Update
método; ¿La instrucción_usingMethod1 = true
se ejecuta siempre antes de obtener o configurar la propiedad? o debido a un problema de reordenamiento, no podemos garantizar eso?debemos utilizar
volatile
comoprivate volatile bool _usingMethod1 = false;
Si utilizamos
lock;
podemos garantizar entonces cada declaración dentro de la cerradura se ejecutará en orden como:private void FooMethod() { object locker = new object(); lock (locker) { x = 1; y = a; i++; } }
Gracias por la información, realmente me ayuda a entender el concepto más ... Lo que necesito lograr es asegurarme de que la instrucción "_usingMethod1 = true" siempre se realice antes de la siguiente instrucción SomeProperty = FooMethod(); En el senario multithread ¿cómo lograr eso? es por: _usingMethod1 = true; Thread.MemoryBarrier(); SomeProperty = FooMethod(); o bloqueo para vallas completas, por lo que no se debe volver a marcar: bloqueo (casillero) {_usingMethod1 = true; } SomeProperty = FooMethod(); o tal vez simplemente haciendo que _usingMethod1 sea una variable volátil. Gracias por tu ayuda. –
Me gustaría envolver todo el contenido del método de actualización en un bloqueo. Además de las barreras de memoria, también garantiza la atomicidad, que es igualmente importante. Además, estos modismos sin bloqueo (a través de volátiles, Thread.MemoryBarrier, etc.) son increíblemente difíciles de corregir. –