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 | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| P0558R1 | C++11 |
由于
T
是从多个参数推导得出,因此需要精确类型匹配
|
T
仅从
obj 推导得出 |
参见
|
原子地从原子对象存储的值中减去参数并获取先前持有的值
(
std::atomic<T>
的公开成员函数)
|
|
|
(C++11)
(C++11)
|
将非原子值加到原子对象上并获取该原子的先前值
(函数模板) |
|
C 文档
用于
atomic_fetch_sub
,
atomic_fetch_sub_explicit
|
|