根据Are C++ Reads and Writes of an int Atomic?,由于处理器缓存的问题,int的读取(以及因此指针 - 或者我认为)在C中不是原子的。所以,我的问题是我可以使用一些程序集用来制作读取原子,还是需要使用锁?我查看了几组原子操作库,到目前为止,我无法找到原子读取函数。
编辑:编译: Clang 2.9 编辑:平台: x86(64位)
感谢。
答案 0 :(得分:6)
通常,原子操作库不提供简单的原子提取,因为它很少使用;你读取了值然后用它做了一些事情,并且需要在那个事情期间保持锁定,以便你知道你读取的值没有改变。因此,有一种原子测试和集合(例如gcc
的{{1}})执行锁定,然后在执行锁定时执行正常的非同步读取,而不是原子读取
例外是设备驱动程序,您可能必须实际锁定系统总线以获得相对于总线上其他设备的原子性,或者实现原子操作库的锁定原语;这些本质上是机器特定的,你将不得不深入研究汇编语言。在x86处理器上,有各种原子指令,加上__sync_fetch_and_add()
前缀,可以应用于访问内存并在操作期间保持总线锁定的大多数操作;其他平台(SPARC,MIPS等)具有类似的机制,但通常细节不同。您必须知道您正在编程的CPU,并且在这种情况下很可能必须了解机器的总线架构。这个库很少有意义,因为你不能跨函数入口/出口保持总线或内存锁,即使使用宏库也必须要小心,因为暗示人们可能在宏调用之间散布正常操作可能会破坏锁定的事实。用汇编语言编写整个关键部分几乎总是更好。
答案 1 :(得分:5)
gcc有一组原子内置函数,但它没有普通的原子提取,但是你可以用__sync_fetch_and_add(&<your variable here>, 0);
来解决这个问题
GCC文档是here,上面有博客文章
编辑:啊,铿锵,我知道LLVM IR里面有原子,但是我不知道clang是否以任何方式暴露它们,但是它可能值得一试,看它是否抱怨使用gcc,它可能会支持他们。编辑:嗯,似乎有一些东西...... clang docs没有gcc那么多,而且文档似乎暗示它也可以做gcc的。