Espacios de nombres
Variantes
Acciones

std::atomic_fetch_sub, std::atomic_fetch_sub_explicit

De cppreference.com
< cpp‎ | atomic
 
 
 
Definido en el archivo de encabezado <atomic>
(1)
template< class T >

T atomic_fetch_sub( std::atomic<T>* obj,

                    typename std::atomic<T>::difference_type arg ) noexcept;
template< class T >

T atomic_fetch_sub( volatile std::atomic<T>* obj,

                    typename std::atomic<T>::difference_type arg ) noexcept;
(2)
template< class T >

T atomic_fetch_sub_explicit( std::atomic<T>* obj,
                             typename std::atomic<T>::difference_type arg,

                             std::memory_order order ) noexcept;
template< class T >

T atomic_fetch_sub_explicit( volatile std::atomic<T>* obj,
                             typename std::atomic<T>::difference_type arg,

                             std::memory_order order ) noexcept;

Realiza una resta atómica. Atómicamente resta arg del valor al que apunta obj y devuelve el valor que obj tenía previamente. La operación se realiza como si se ejecutara lo siguiente:

1) obj->fetch_sub(arg)
2) obj->fetch_sub(arg, order)

Contenido

[editar] Parámetros

obj - Puntero al objeto atómico a modificar.
arg - El valor a restar del valor almacenado en el objeto atómico.
order - El orden de sincronización de la memoria para esta operación: todos los valores están permitidos.

[editar] Valor de retorno

El valor que precede inmediatamente a los efectos de esta función en el orden de modificación de *obj.

[editar] Posible implementación

template< class T >
T atomic_fetch_sub( std::atomic<T>* obj,
                    typename std::atomic<T>::difference_type arg ) noexcept
{
    return obj->fetch_sub(arg);
}

[editar] Ejemplo

Varios hilos pueden usar fetch_sub para procesar concurrentemente un contenedor indexado.

#include <string>
#include <thread>
#include <vector>
#include <iostream>
#include <atomic>
#include <numeric>
 
const int N = 50;
std::atomic<int> cnt;
std::vector<int> data(N);
 
void lector(int id) 
{
    for (;;) {
        int idx = atomic_fetch_sub_explicit(&cnt, 1, std::memory_order_relaxed);
        if (idx >= 0) {
            std::cout << "lector " << std::to_string(id) << " ha procesado elemento "
                      << std::to_string(data[idx]) << '\n';
        } else {
            std::cout << "lector " << std::to_string(id) << " listo\n";
            break;
        }
    }
}
 
int main()
{
    std::iota(data.begin(), data.end(), 1);
    cnt = data.size() - 1;
 
    std::vector<std::thread> v;
    for (int n = 0; n < 5; ++n) {
        v.emplace_back(lector, n);
    }
    for (auto& t : v) {
        t.join();
    }
}

Salida:

lector 2 ha procesado elemento 50
lector 1 ha procesado elemento 44
lector 4 ha procesado elemento 46
<....>
lector 0 listo
lector 4 listo
lector 3 listo

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
P0558R1 C++11 Se requiere una coincidencia de tipo exacta porque T
se deduce de varios argumentos.
T se deduce únicamente del argumento atomic.

[editar] Véase también

(C++11)
atómicamente resta el argumento de que el valor almacenado en el objeto atómico y obtiene el valor que tenía antes
Original:
atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

(función miembro pública de std::atomic) [editar]
Agrega un valor no atómico a un objeto atómico y obtiene el valor anterior del objeto atómico.
(plantilla de función) [editar]
Documentación de C para atomic_fetch_sub, atomic_fetch_sub_explicit