Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确使用std::atomic_signal_fence()?_C++_Multithreading_Performance_C++11_Atomic - Fatal编程技术网

C++ 如何正确使用std::atomic_signal_fence()?

C++ 如何正确使用std::atomic_signal_fence()?,c++,multithreading,performance,c++11,atomic,C++,Multithreading,Performance,C++11,Atomic,cppreference.com将此函数记录为“在同一线程中执行的线程和信号处理程序之间的隔离”。但我在网上找不到任何例子 我想知道下面的psuedo代码是否正确地说明了std::atomic\u signal\u fence(): 不,您的代码没有演示原子信号围栏的正确用法。正如您引用的cppreference.com所述,atomic\u signal\u fence仅在信号处理程序和同一线程上运行的其他代码之间执行同步。这意味着它不会在两个不同的线程之间执行同步。您的示例代码显示了两个不同

cppreference.com将此函数记录为“在同一线程中执行的线程和信号处理程序之间的隔离”。但我在网上找不到任何例子

我想知道下面的psuedo代码是否正确地说明了
std::atomic\u signal\u fence()


不,您的代码没有演示原子信号围栏的正确用法。正如您引用的cppreference.com所述,
atomic\u signal\u fence
仅在信号处理程序和同一线程上运行的其他代码之间执行同步。这意味着它不会在两个不同的线程之间执行同步。您的示例代码显示了两个不同的线程

C++规范包含以下关于这个函数的注释:

注意:编译器优化以及加载和存储的重新排序与使用
原子线程围栏
的方式相同,但不会发出原子线程围栏将插入的硬件围栏指令

注意:
atomic\u signal\u fence
可用于指定线程执行的操作对信号处理程序可见的顺序

下面是一个正确(如果不是激励)用法的示例:

static_assert(2 == ATOMIC_INT_LOCK_FREE, "this implementation does not guarantee that std::atomic<int> is always lock free.");

std::atomic<int> a = 0;
std::atomic<int> b = 0;

extern "C" void handler(int) {
    if (1 == a.load(std::memory_order_relaxed)) {
        std::atomic_signal_fence(std::memory_order_acquire);
        assert(1 == b.load(std::memory_order_relaxed));
    }

    std::exit(0);
}

int main() {
    std::signal(SIGTERM, &handler);

    b.store(1, std::memory_order_relaxed);
    std::atomic_signal_fence(std::memory_order_release);
    a.store(1, std::memory_order_relaxed);
}
static_assert(2==ATOMIC_INT_LOCK_FREE,“此实现不保证std::ATOMIC始终是无锁的。”);
标准::原子a=0;
标准::原子b=0;
外部“C”无效处理程序(int){
if(1==a.load(标准::内存\u顺序\u松弛)){
std::原子信号围栏(std::内存顺序获取);
断言(1==b.load(std::memory_order_released));
}
std::出口(0);
}
int main(){
标准::信号(SIGTERM和处理器);
b、 存储(1,标准::内存\u顺序\u松弛);
std::原子信号围栏(std::内存命令释放);
a、 存储(1,标准::内存\u顺序\u松弛);
}

如果遇到断言,则该断言保证为真。

在您的示例中,您希望使用
std::atomic_thread_fence
(它生成执行线程同步的机器代码);not
std::atomic\u signal\u fence
(它仅禁用对原子变量的编译器内存重新排序优化)。
正如其他人所说,
std::atomic_signal_fence
仅适用于与原子操作相同线程上的信号(我相信它也适用于Windows上的结构化/向量化异常处理程序,但不要引用我的话)。

我认为信号处理程序是unix系统类型信号中的一种,它有特殊的线程规则。您的代码中没有任何信号处理程序,因此不,代码没有显示任何关于
原子信号围栏
@StefanDragnev的有意义的内容-有了适当的围栏,就不需要
volatile
。这就是原子学和fences的全部内容。@StefanDragnev-不,如果使用fences或任何其他原子操作(使用适当的内存访问说明符),编译器是不允许这样做的。在这种情况下,
volatile
是多余的。
信号栅栏
是一种:它阻止编译时内存操作的重新排序/组合/提升,但永远不会发出硬件内存屏障指令。杰夫·普雷辛(Jeff Preshing)的博客非常擅长解释这些东西,如果你不确定内存排序的东西,那么一定要阅读。在你的例子中a和B一定是原子的吗?@Alex他们需要原子性。从技术上讲,它几乎从来没有保证过没有原子。
static_assert(2 == ATOMIC_INT_LOCK_FREE, "this implementation does not guarantee that std::atomic<int> is always lock free.");

std::atomic<int> a = 0;
std::atomic<int> b = 0;

extern "C" void handler(int) {
    if (1 == a.load(std::memory_order_relaxed)) {
        std::atomic_signal_fence(std::memory_order_acquire);
        assert(1 == b.load(std::memory_order_relaxed));
    }

    std::exit(0);
}

int main() {
    std::signal(SIGTERM, &handler);

    b.store(1, std::memory_order_relaxed);
    std::atomic_signal_fence(std::memory_order_release);
    a.store(1, std::memory_order_relaxed);
}