Espacios de nombres
Variantes

std::atomic_flag_test_and_set, std::atomic_flag_test_and_set_explicit

De cppreference.com
 
 
 
Definido en el archivo de encabezado <atomic>
bool atomic_flag_test_and_set( volatile std::atomic_flag* p ) noexcept;
bool atomic_flag_test_and_set( std::atomic_flag* p ) noexcept;
bool atomic_flag_test_and_set_explicit( volatile std::atomic_flag* p, 
                                        std::memory_order order ) noexcept;
bool atomic_flag_test_and_set_explicit( std::atomic_flag* p, 
                                        std::memory_order order ) noexcept;

Cambia atómicamente el estado de la bandera std::atomic_flag a la que apunta p para establecerla (a true) y devuelve el valor que tenía anteriormente.

Parámetros

p - Un puntero a la bandera std::atomic_flag a acceder.
order - El ordenamiento de sincronización de memoria para esta operación.

Valor de retorno

El valor que anteriormente tenía la bandera a la que apunta p.

Posible implementación

Primera versión
bool atomic_flag_test_and_set(volatile std::atomic_flag* p)
{
    return p->test_and_set();
}
Segunda versión
bool atomic_flag_test_and_set(std::atomic_flag* p)
{
    return p->test_and_set();
}
Tercera versión
bool atomic_flag_test_and_set_explicit(volatile std::atomic_flag* p, 
                                       std::memory_order order)
{
    return p->test_and_set(order);
}
Cuarta versión
bool atomic_flag_test_and_set_explicit(std::atomic_flag* p, 
                                       std::memory_order order) 
{
    return p->test_and_set(order);
}

Ejemplo

Un mutex de espín puede implementarse en el espacio de usuarios usando un objeto atomic_flag.

#include <thread>
#include <vector>
#include <iostream>
#include <atomic>

std::atomic_flag lock = ATOMIC_FLAG_INIT;

void f(int n)
{
    for (int cnt = 0; cnt < 100; ++cnt) {
        while(std::atomic_flag_test_and_set_explicit(&lock, std::memory_order_acquire))
             ; // girar hasta que se adquiera el cerrojo
        std::cout << "Salida del hilo " << n << '\n';
        std::atomic_flag_clear_explicit(&lock, std::memory_order_release);
    }
}

int main()
{
    std::vector<std::thread> v;
    for (int n = 0; n < 10; ++n) {
        v.emplace_back(f, n);
    }
    for (auto& t : v) {
        t.join();
    }
}

Salida:

Salida del hilo 2
Salida del hilo 6
Salida del hilo 7
...<exactamente 1000 líneas>...

Véase también

El tipo atómico booleano libre de bloqueo.
(clase) [editar]
Establece atómicamente el valor de la bandera a false.
(función) [editar]
Define las restricciones del ordenamiento de memoria para la operación atómica dada.
(typedef) [editar]
Documentación de C para atomic_flag_test_and_set, atomic_flag_test_and_set_explicit