Estoy pensando en si es posible o no que la variable atómica cargue el valor anterior en el par adquirir-liberar. Supongamos que tenemos la variable atómica x, y almacenamos esa variable con semántica de lanzamiento y luego la cargamos con semántica de adquisición ¿es posible en teoría leer el valor anterior?adquisición-liberación par ejecución fuera de servicio
std::atomic<int> x = 0;
void thread_1()
{
x.store(1, std::memory_order_release);
}
void thread_2()
{
assert(x.load(std::memory_order_acquire) != 0);
}
si hilo función 1 se termina cuando hilo cargas de 2 x (lo que el nuevo valor se almacena) ¿Es posible para el hilo 2 para cargar valor antiguo de x? En otras palabras, si el almacenamiento real en x se realiza antes de que la carga sea posible para afirmar disparar?
Por lo que he entendido por artículos en internet, es posible, pero no puedo entender por qué. La valla de memoria generada por la tienda en x garantías para vaciar la memoria intermedia de la tienda, mientras que la validación de memoria en la carga de x garantiza la invalidación de la línea de caché, por lo que debe leer el valor actualizado.
añade
¿Significa que adquieren de liberación por sí misma no tiene ningún pedido forzada? Es todo lo que se hizo antes de que se produzca el lanzamiento antes del lanzamiento y todo lo que se hace después de adquirir se producirá después de él, por lo que el par adquirir-liberar impone el orden en las otras operaciones (¿por qué?). ¿Lo entendí bien? ¿Quiere decir que en la aserción código de abajo se garantiza que no dispare
std::atomic<int> x = 0;
std::atomic<int> y = 0;
void thread_1()
{
y.store(1, std::memory_order_relaxed);
x.store(1, std::memory_order_release);
}
void thread_2()
{
x.load(std::memory_order_acquire);
assert(y.load(std::memory_order_relaxed) != 0);
}
por supuesto de nuevo si el hilo 1 ya se terminó la tienda. Si reemplazamos x.load con while (x.load() == 0), esto funcionará al 100%, pero no sé qué causa que esto funcione.
¿Y si puedo reemplazar el código con el código de abajo
std::atomic<int> x = 0;
void thread_1()
{
x.exchange(1, std::memory_order_acq_rel);
}
void thread_2()
{
assert(x.exchange(0, std::memory_order_acq_rel) != 0);
}
¿Cambia algo?
Gracias.
Quiero saber si no se garantiza que no se dispare (por supuesto en caso de que la tienda real se haya realizado antes de la carga). – axl
sí, su edición ya lo había aclarado. Mi comentario fue escrito antes de que tu edición fuera mostrada. –