C11 atomic_load/store 和 volatile 限定词
C11 atomic_load/store and volatile qualifier
为什么C11 atomic_load
/atomic_store
函数中的参数有volatile
限定符?众所周知,volatile
对于并发用例是无用的(例如 1, 2)。
atomic_load( const volatile A* obj );
void atomic_store( volatile A* obj , C desired);
首先,你的假设是错误的,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
这里的"should"是因为我上面提到的volatile
的不同解释。如果你想确保没有发生负载优化,你也应该始终声明你的 _Atomic
对象 volatile
。它不会造成太大伤害,但在某些极端情况下可能会有所帮助。
语义原子操作意味着有多个并发线程访问变量值。这就是 volatile
说明符的用途。
您提供的两个参考资料都非常有问题并且不普遍适用(在 SW 工程中通常如此)。如果你有数据,在软件里可以同时accessed/modified,那必须是volatile
.
有一些用例,其中 volatile
是绝对必要的:内核驱动程序。您不能让编译器优化对映射到设备的内存区域的访问。
有很多基于volatile
的编程范式。例如,普通关键 sections/mutexes 使用 volatile
变量进行快速锁定,仅当快速锁定失败时才回退到 signals/events/etc。
为什么C11 atomic_load
/atomic_store
函数中的参数有volatile
限定符?众所周知,volatile
对于并发用例是无用的(例如 1, 2)。
atomic_load( const volatile A* obj );
void atomic_store( volatile A* obj , C desired);
首先,你的假设是错误的,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
这里的"should"是因为我上面提到的volatile
的不同解释。如果你想确保没有发生负载优化,你也应该始终声明你的 _Atomic
对象 volatile
。它不会造成太大伤害,但在某些极端情况下可能会有所帮助。
语义原子操作意味着有多个并发线程访问变量值。这就是 volatile
说明符的用途。
您提供的两个参考资料都非常有问题并且不普遍适用(在 SW 工程中通常如此)。如果你有数据,在软件里可以同时accessed/modified,那必须是volatile
.
有一些用例,其中 volatile
是绝对必要的:内核驱动程序。您不能让编译器优化对映射到设备的内存区域的访问。
有很多基于volatile
的编程范式。例如,普通关键 sections/mutexes 使用 volatile
变量进行快速锁定,仅当快速锁定失败时才回退到 signals/events/etc。