std:: atomic_fetch_sub, std:: atomic_fetch_sub_explicit
|
Определено в заголовочном файле
<atomic>
|
||
|
template
<
class
T
>
T atomic_fetch_sub
(
std::
atomic
<
T
>
*
obj,
|
(1) | (начиная с C++11) |
|
template
<
class
T
>
T atomic_fetch_sub
(
volatile
std::
atomic
<
T
>
*
obj,
|
(2) | (начиная с C++11) |
|
template
<
class
T
>
T atomic_fetch_sub_explicit
(
std::
atomic
<
T
>
*
obj,
|
(3) | (начиная с C++11) |
|
template
<
class
T
>
T atomic_fetch_sub_explicit
(
volatile
std::
atomic
<
T
>
*
obj,
|
(4) | (начиная с C++11) |
Выполняет атомарное вычитание. Атомарно вычитает arg из значения, на которое указывает obj и возвращает значение, которое obj содержал ранее. Операция выполняется так, как если бы был выполнен следующий код:
Если
std::atomic<T>
не имеет члена
fetch_sub
(этот член предоставляется только для
целочисленных
,
чисел с плавающей запятой
(начиная с C++20)
и
указательных
типов, за исключением
bool
), программа является некорректной.
Содержание |
Параметры
| obj | - | указатель на атомарный объект для модификации |
| arg | - | значение для вычитания из значения, хранящегося в атомарном объекте |
| order | - | порядок синхронизации памяти |
Возвращаемое значение
Значение, непосредственно предшествующее эффектам этой функции в порядке модификации объекта * obj .
Пример
Несколько потоков могут использовать
std::atomic_fetch_sub
для параллельной обработки индексированного контейнера.
#include <atomic> #include <iostream> #include <numeric> #include <string> #include <thread> #include <vector> const int N = 50; std::atomic<int> cnt; std::vector<int> data(N); void reader(int id) { for (;;) { int idx = atomic_fetch_sub_explicit(&cnt, 1, std::memory_order_relaxed); if (idx >= 0) std::cout << "reader " << std::to_string(id) << " processed item " << std::to_string(data[idx]) << '\n'; else { std::cout << "reader " << std::to_string(id) << " done\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(reader, n); for (auto& t : v) t.join(); }
Вывод:
reader 2 processed item 50 reader 1 processed item 44 reader 4 processed item 46 <....> reader 0 done reader 4 done reader 3 done
Отчёты о дефектах
Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| P0558R1 | C++11 |
требовалось точное соответствие типов, потому что
T
выводился из нескольких аргументов
|
T
выводится только
из obj |
Смотрите также
|
атомически вычитает аргумент из значения, хранящегося в атомарном объекте, и получает значение, хранившееся ранее
(публичная функция-член
std::atomic<T>
)
|
|
|
(C++11)
(C++11)
|
добавляет неатомарное значение к атомарному объекту и получает предыдущее значение атомарного объекта
(шаблон функции) |
|
Документация C
для
atomic_fetch_sub
,
atomic_fetch_sub_explicit
|
|