为什么C11 atomic_load
/ atomic_store
函数中的参数具有volatile
限定符?众所周知,volatile
对并发用例无效(例如1,2)。
atomic_load( const volatile A* obj );
void atomic_store( volatile A* obj , C desired);
答案 0 :(得分:5)
首先,你的假设是假的,volatile
没有用,只是不够,这是另一回事。
您引用的接口必须具有volatile
资格,否则它们将无法用于合格的对象。
现在volatile
对于C11来说是一个困难的主题,因为目前有争议的是它是否只有在对象本身是volatile
限定的情况下才有效,或者只是当前访问它的类型。但可以肯定的是,这里的_Atomic
个对象的规则与其他对象没有太大的不同。因此,如果您的非volatile
访问权限也未进行修改,则编译器可以优化该访问权限并依赖于之前已知的值。
您可以使用_Atomic
进行的唯一此类操作正在对其进行评估:
_Atomic size_t counter = ATOMIC_VAR_INIT(0);
++counter; // safe: sequential consistency
...
printf("counter: %zu\n", counter); // may use some previous value
...
printf("counter: %zu\n", atomic_load(&counter)); // should use actual value
现在"应该"这是因为我上面提到的关于volatile
的不同解释。如果您想确保不进行任何加载优化,则应始终声明_Atomic
个对象volatile
。它不会造成太大的伤害,但在某些极端情况下可能会有所帮助。
答案 1 :(得分:-2)
语义上的原子操作意味着有多个并发线程访问变量值。这就是volatile
说明符的用途。
您提供的两个参考文献都非常有问题,并且通常不适用(通常在SW工程中)。如果您有可以在软件中同时访问/修改的数据,则必须是volatile
。
有些用例,其中volatile
是绝对必要的:内核驱动程序。您不能让编译器优化对映射到设备的内存区域的访问。
有许多基于volatile
的编程范例。例如,正常的关键部分/互斥体使用volatile
变量来快速锁定并仅在快速锁定失败时回退到信号/事件/等。