es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe alguna forma de tener una versión del método compare_exchange_strong de std::atomic que intercambie en caso de desigualdad?

Tengo un tipo atómico en el que necesito compararlo atómicamente con un valor, y si los dos valores no son iguales, intercambiar el valor del atómico.

En otras palabras, donde compare_exchange_strong básicamente realiza esta operación atómicamente:

if (atomic_value == expected)
    atomic_value = desired;

…Estoy buscando una forma de hacer esto:

if (atomic_value != expected)
    atomic_value = desired;

(Sí, sé que compare_exchange_strong compara usando igualdad a nivel de bits, no el operador ==. Y sé que el valor de expected se asigna cuando la comparación falla. Esto fue solo con fines ilustrativos. En mi caso de uso, no necesito el valor del atómico sin importar el resultado de la comparación).

¿Hay alguna forma de hacer esto sin tener que recurrir a usar un bloqueo en lugar de std::atomic?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una manera de hacer esto sin usar un candado. Puedes utilizar el método compare_exchange_weak, que devuelve un bool indicando si la comparación fue exitosa o no. Si la comparación falla, puedes asignar el valor deseado al atómico. Aquí tienes un ejemplo:

    “`c++
    std::atomic atomic_value(5);
    int expected = 5;
    int desired = 10;

    while(!atomic_value.compare_exchange_weak(expected, desired))
    {
    expected = atomic_value.load(); // actualizar expected con el valor actual del atómico
    }

    // En este punto, el valor de atomic_value se ha actualizado a 10 si originalmente era 5.
    “`

    En este ejemplo, primero intentamos comparar atómicamente atomic_value con expected. Si son iguales, compare_exchange_weak devuelve true y no necesitamos hacer nada más. Si no son iguales, compare_exchange_weak devuelve false y actualizamos expected con el valor actual de atomic_value utilizando load(). Luego intentamos la comparación nuevamente. Si tiene éxito, hemos terminado. Si falla nuevamente, repetimos el proceso hasta que la comparación tenga éxito.

    Una vez que el bucle sale, atomic_value tiene el valor original de 5 si la comparación fue exitosa (porque no lo actualizamos), o el nuevo valor de 10 si la comparación falló (porque lo actualizamos dentro del bucle).

Comments are closed.