std::atomic_fetch_add, std::atomic_fetch_add_explicit
|
|
This page has been machine-translated from the English version of the wiki using Google Translate.
The translation may contain errors and awkward wording. Hover over text to see the original version. You can help to fix errors and improve the translation. For instructions click here. |
<metanoindex/>
<tbody> </tbody>| definiert in Header <atomic>
|
||
template< class Integral > Integral atomic_fetch_add( std::atomic<Integral>* obj, Integral arg ); |
(1) | (seit C++11) |
template< class Integral > Integral atomic_fetch_add( volatile std::atomic<Integral>* obj, Integral arg ); |
(2) | (seit C++11) |
template< class Integral > Integral atomic_fetch_add_explicit( std::atomic<Integral>* obj, Integral arg, std::memory_order order ); |
(3) | (seit C++11) |
template< class Integral > Integral atomic_fetch_add_explicit( volatile std::atomic<Integral>* obj, Integral arg, std::memory_order order ); |
(4) | (seit C++11) |
template< class T > T* atomic_fetch_add( std::atomic<T*>* obj, std::ptrdiff_t arg ); |
(5) | (seit C++11) |
template< class T > T* atomic_fetch_add( volatile std::atomic<T*>* obj, std::ptrdiff_t arg ); |
(6) | (seit C++11) |
template< class T > T* atomic_fetch_add_explicit( std::atomic<T*>* obj, std::ptrdiff_t arg, std::memory_order order ); |
(7) | (seit C++11) |
template< class T > T* atomic_fetch_add_explicit( volatile std::atomic<T*>* obj, std::ptrdiff_t arg, std::memory_order order ); |
(8) | (seit C++11) |
1-2) Atomically adds arg to the value pointed to by obj and returns the value obj held previously, as if by obj->fetch_add(arg)
3-4) Atomically adds arg to the value pointed to by obj and returns the value obj held previously, as if by obj->fetch_add(arg, order)
5-6) Atomically increments the pointer value, pointed to by obj, by arg, and returns the value obj held previously, as if by obj->fetch_add(arg)
7-8) Atomically increments the pointer value, pointed to by obj, by arg, and returns the value obj held previously, as if by obj->fetch_add(arg, order)
Parameter
| obj | - | Zeiger auf den atomaren Objekts zu ändern
Original: pointer to the atomic object to modify The text has been machine-translated via Google Translate. You can help to correct and verify the translation. Click here for instructions. |
| arg | - | der Wert, der dem Wert in der atomaren Objekt gespeichert hinzuzufügen
Original: the value to add to the value stored in the atomic object The text has been machine-translated via Google Translate. You can help to correct and verify the translation. Click here for instructions. |
| order | - | der Speicher sycnhronization Bestellung für diesen Vorgang: Alle Werte sind zulässig .
Original: the memory sycnhronization ordering for this operation: all values are permitted. The text has been machine-translated via Google Translate. You can help to correct and verify the translation. Click here for instructions. |
Rückgabewert
objobjYou can help to correct and verify the translation. Click here for instructions.
Ausnahmen
Mögliche Implementierung
| First version |
|---|
template< class T >
typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, T>::type
atomic_fetch_add( std::atomic<T>* obj, T arg );
{
return obj->fetch_add(arg);
}
|
| Second version |
template< class T >
T* atomic_fetch_add( std::atomic<T*>* obj, std::ptrdiff_t arg)
{
return obj->fetch_add(arg);
}
|
Beispiel
Single-writer/multiple-reader lock can be made with fetch_add. Note that this simplistic implementation is not lockout-free
#include <string>
#include <thread>
#include <vector>
#include <iostream>
#include <atomic>
#include <chrono>
// meaning of cnt:
// 10: there are no active readers or writers.
// 1...9: there are 9...1 readers active, The writer is blocked
// 0: temporary value between fetch_sub and fetch_add in reader lock
// -1: there is a writer active. The readers are blocked.
const int N = 10; // nine concurrent readers are allowed
std::atomic<int> cnt = ATOMIC_VAR_INIT(N);
std::vector<int> data;
void reader(int id)
{
for(;;)
{
// lock
while(std::atomic_fetch_sub(&cnt, 1) <= 0)
std::atomic_fetch_add(&cnt, 1);
// read
if(!data.empty())
std::cout << ( "reader " + std::to_string(id)
+ " sees " + std::to_string(*data.rbegin()) + '\n');
if(data.size() == 100)
break;
// unlock
std::atomic_fetch_add(&cnt, 1);
// pause
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
void writer()
{
for(int n = 0; n < 100; ++n)
{
// lock
while(std::atomic_fetch_sub(&cnt, N+1) != N)
std::atomic_fetch_add(&cnt, N+1);
// write
data.push_back(n);
std::cout << "writer pushed back " << n << '\n';
// unlock
std::atomic_fetch_add(&cnt, N+1);
// pause
std::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(reader, n);
}
v.emplace_back(writer);
for (auto& t : v) {
t.join();
}
}
Output:
writer pushed back 0
reader 8 sees 0
reader 3 sees 0
reader 1 sees 0
<...>
reader 2 sees 99
reader 6 sees 99
reader 1 sees 99
Siehe auch
(C++11) |
atomar fügt das Argument zu dem Wert in dem atomaren Objekt gespeichert und erhält den Wert gehalten zuvor 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. (öffentliche Elementfunktion of std::atomic)
|
(C++11) (C++11) |
subtrahiert eine nicht-elementare Wert aus einer atomaren Objekt und erhält den vorherigen Wert des atomaren Original: subtracts a non-atomic value from an atomic object and obtains the previous value of the atomic The text has been machine-translated via Google Translate. You can help to correct and verify the translation. Click here for instructions. (Funktions-Template) |
C documentation for atomic_fetch_add, atomic_fetch_add_explicit
| |