我试图了解 C11 内存模型是如何工作的,并编写了两个包含表达式的函数conflict
(在 的意义上5.1.2.4(p4)
):
struct my_struct{
uint64_t first;
int64_t second;
} * _Atomic instance;
void* set_first(void *ignored){
uint64_t i = 0;
while(1){
struct my_struct *ms = atomic_load_explicit(&instance, memory_order_acquire);
ms -> first = i++;
atomic_store_explicit(&instance, ms, memory_order_release);
sleep(1);
}
}
void* print_first(void *ignored){
while(1){
struct my_struct *ms = atomic_load_explicit(&instance, memory_order_acquire);
uint64_t current = ms -> first;
char buf[100];
memset(buf, '\0', sizeof(buf));
sprintf(buf, "%" PRIu64 "\n", current);
fputs_unlocked(buf, stdout);
sleep(2);
}
}
主要功能:
int main(void){
struct my_struct tmp = {.first = 0, .second = 0};
atomic_init(&instance, &tmp);
printf("main\n");
pthread_t set_thread;
pthread_create(&set_thread, NULL, &set_first, NULL);
pthread_t print_thread;
pthread_create(&print_thread, NULL, &print_first, NULL);
while(1){
sleep(100);
}
}
所以我试图证明程序是否不包含 data-races。以下是我的想法:
我们知道原子对象上的释放操作与对象上的获取操作同步。所以
atomic_store_explicit(&instance, ms, memory_order_release);
在 中与中set_first
同步 。atomic_load_explicit(&instance, memory_order_acquire)
print_first
ms -> first = i++
由于函数中的副作用set_first
出现在atomic_store_explicit(&instance, ms, memory_order_release);
程序文本之前,我假设它是在它之前排序的(这是我不确定的,找不到任何规范性参考)。结合项目符号
1.
并2.
暗示ms -> first = i++
线程间发生在之前,atomic_load_explicit(&instance, memory_order_acquire);
因此它们在关系之前发生。应用数据竞争定义,我们得出结论,函数和函数
uint64_t current = ms -> first;
中的冲突操作不会产生数据竞争。print_first
ms -> first = i++;
set_first
所以行为似乎是明确定义的。
可疑的事情被假定为ms -> first = i++;
之前排序, atomic_store_explicit(&instance, ms, memory_order_release);
因为它们在程序文本中一个接一个地发生。
它是正确的还是程序包含数据竞争?