Namespaces
Variants

std:: kill_dependency

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
kill_dependency
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
定义于头文件 <atomic>
template < class T >
T kill_dependency ( T y ) noexcept ;
(C++11 起)
(C++26 起为 constexpr)
(C++26 起弃用)

通知编译器:由 std::memory_order_consume 原子加载操作开始的依赖树不会延伸至 std::kill_dependency 的返回值之后;即参数不会将依赖关系传递到返回值中。

当依赖链离开函数作用域(且该函数不带有 [[ carries_dependency ]] 属性)时,可通过此方法避免不必要的 std::memory_order_acquire 栅栏。

(C++26 前)

直接返回 y 。此函数模板已被弃用。

(C++26 起)

目录

参数

y - 要从依赖树中移除其返回值的表达式

返回值

返回 y ,不再属于依赖树 (until C++26)

示例

file1.cpp:
struct Foo
{
    int* a;
    int* b;
};
std::atomic<Foo*> foo_head[10];
int foo_array[10][10];
// consume操作启动依赖链,该依赖链将逃逸出此函数
[[carries_dependency]] Foo* f(int i)
{
    return foo_head[i].load(memory_order_consume);
}
// 依赖链通过右侧参数传入此函数,并在函数结束前被消除(因此不会发生额外的acquire操作)
int g(int* x, int* y [[carries_dependency]])
{
    return std::kill_dependency(foo_array[*x][*y]);
}
file2.cpp:
[[carries_dependency]] struct Foo* f(int i);
int g(int* x, int* y [[carries_dependency]]);
int c = 3;
void h(int i)
{
    Foo* p;
    p = f(i); // 在f内部启动的依赖链继续传递到p中,无需不必要的获取操作
    do_something_with(g(&c, p->a)); // p->b不会从缓存中引入
    do_something_with(g(p->a, &c)); // 左侧参数不具备carries_dependency属性
                                    // 可能会发出内存获取栅栏
                                    // 在进入g()之前p->b变为可见
}

参见

为给定的原子操作定义内存排序约束
(枚举)
C 文档 关于 kill_dependency