有没有办法使用栅栏来推理 C11 中非原子操作的行为?具体来说,我希望在某些字段需要为int
s 以与旧接口兼容的情况下使代码安全,例如,可能将数据结构读取和写入文件或将它们作为系统调用参数传递。由于没有要求 aatomic_int
甚至与 a 大小相同int
,因此我不能使用 a atomic_int
。
这是一个最小的工作示例,不幸的是根据第 5.1.2.4 节第 25 节产生未定义的行为,因为数据竞争ready
:
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>
int ready; /* purposely NOT _Atomic */
int value;
void
p1()
{
value = 1;
atomic_thread_fence(memory_order_release);
ready = 1;
}
void
p2(void *_ignored)
{
while (!ready)
;
atomic_thread_fence(memory_order_acquire);
printf("%d\n", value);
}
int
main()
{
thrd_t t;
thrd_create(&t, p2, NULL);
p1();
thrd_join(&t, NULL);
}
我的具体问题是是否可以修复上述代码以保证打印1
而不更改ready
为_Atomic
. (我可以做ready
一个volatile
,但在规范中看不到任何有帮助的建议。)
一个相关的问题是无论如何编写上述代码是否安全,因为我的代码将在其上运行的任何机器都具有缓存一致性?我知道当 C11 程序包含所谓的良性竞争时,很多 事情都会出错,所以我真的在寻找合理的编译器和架构可以对上述代码做什么的细节,而不是关于数据竞争和未定义的一般警告行为。