单线程场景下std::system_clock::now()与内存屏障的技术疑问
单线程下内存屏障与系统调用的疑问解答
代码需求与示例
我需要在代码中添加两个内存屏障,防止编译器或CPU对代码进行重排序,确保rec.time_stamp0 = std::system_clock::now();必定在中间所有代码之前执行,且rec.time_stamp1 = std::system_clock::now();必须在中间所有代码之后执行。给出的代码示例如下:
rec.time_stamp0 = std::system_clock::now(); std::atomic_signal_fence( std::memory_order::release ); /* do many things... */ std::atomic_signal_fence( std::memory_order::acquire ); rec.time_stamp1 = std::system_clock::now();
疑问与解答
1. std::system_clock::now()作为系统调用是否原生自带内存屏障,无需显式添加?
std::system_clock::now()的实现依赖于具体平台:
- 主流操作系统的底层系统调用(比如Linux的
clock_gettime、Windows的GetSystemTimePreciseAsFileTime)通常会隐含内存屏障。因为系统调用需要切换到内核态,这个过程中CPU会确保所有前置的用户态指令执行完毕,后续指令不会提前执行。 - 但C++标准并没有强制要求
std::system_clock::now()必须携带内存屏障,不同平台的实现可能存在差异。如果你的代码需要严格的执行顺序保证,不能依赖这种平台特定的隐含行为,必须显式添加内存屏障。
2. 单线程程序应使用std::atomic_thread_fence还是std::atomic_signal_fence?
两者的适用场景有明确区别:
std::atomic_signal_fence的设计目标是同步同一线程内的代码与信号处理函数,它仅能阻止编译器的指令重排序,不保证会阻止CPU层面的指令重排序(部分平台可能有此效果,但标准不做强制要求)。std::atomic_thread_fence即使在单线程场景下,也会同时阻止编译器和CPU的指令重排序,严格保证屏障前后的指令执行顺序。
你的需求是确保单线程内时间戳赋值与中间代码的严格先后顺序,因此应该使用std::atomic_thread_fence,替换后的代码如下:
rec.time_stamp0 = std::system_clock::now(); std::atomic_thread_fence( std::memory_order::release ); /* do many things... */ std::atomic_thread_fence( std::memory_order::acquire ); rec.time_stamp1 = std::system_clock::now();
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

