std::atomic_fetch_add, std::atomic_fetch_add_explicit
Definido en el archivo de encabezado <atomic> | ||
(1) | ||
template<class T > T atomic_fetch_add(std::atomic<T>* obj, | ||
template<class T > T atomic_fetch_add(volatilestd::atomic<T>* obj, | ||
(2) | ||
template<class T > T atomic_fetch_add_explicit(std::atomic<T>* obj, | ||
template<class T > T atomic_fetch_add_explicit(volatilestd::atomic<T>* obj, | ||
Realiza una suma atómica. Atómicamente suma arg
al 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:
Contenido |
[editar]Parámetros
obj | - | Puntero al objeto atómico a modificar. |
arg | - | El valor a sumar al 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_add(std::atomic<T>* obj, typenamestd::atomic<T>::difference_type arg ){return obj->fetch_add(arg);} |
[editar]Ejemplo
Cerrojos de un solo-escritor/múltiples-lectores pueden hacerse con fetch_add. Ten en cuenta que esta implementación simplista no está libre de bloqueo
#include <string>#include <thread>#include <vector>#include <iostream>#include <atomic>#include <chrono> // significado de cnt:// 5: no hay lectores ni escritores activos.// 1...4: hay 4 ... 1 lectores activos, el escritor está bloqueado// 0: valor temporal entre fetch_sub y fetch_add en el bloqueo del lector// -1: hay un escritor activo. Los lectores están bloqueados.constint N =5;// se permiten cuatro lectores concurrentesstd::atomic<int> cnt(N); std::vector<int> data; void lector(int id){for(;;){// bloquearwhile(std::atomic_fetch_sub(&cnt, 1)<=0) std::atomic_fetch_add(&cnt, 1);// readif(!data.empty())std::cout<<("lector "+std::to_string(id)+" ve "+std::to_string(*data.rbegin())+'\n');if(data.size()==25)break;// desbloquear std::atomic_fetch_add(&cnt, 1);// pausastd::this_thread::sleep_for(std::chrono::milliseconds(1));}} void escritor(){for(int n =0; n <25;++n){// bloquearwhile(std::atomic_fetch_sub(&cnt, N+1)!= N) std::atomic_fetch_add(&cnt, N+1);// escribir data.push_back(n);std::cout<<"escritor empujó al final "<< n <<'\n';// desbloquear std::atomic_fetch_add(&cnt, N+1);// pausastd::this_thread::sleep_for(std::chrono::milliseconds(1));}} int main(){std::vector<std::thread> v;for(int n =0; n < N;++n){ v.emplace_back(lector, n);} v.emplace_back(escritor);for(auto& t : v){ t.join();}}
Salida:
escritor empujó al final 0 lector 2 ve 0 lector 3 ve 0 lector 1 ve 0 <...> lector 2 ve 24 lector 4 ve 24 lector 1 ve 24
[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 agrega el argumento con el valor almacenado en el objeto atómico y obtiene el valor que tenía antes Original: atomically adds the argument to 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 ) |
(C++11)(C++11) | Resta un valor no atómico de un objeto atómico y obtiene el valor anterior del objeto atómico. (plantilla de función) |
Documentación de C para atomic_fetch_add, atomic_fetch_add_explicit |