我正在使用 C 语言中的 pthreads。我使用gcc ... -fsanitize=thread -g
. 为了避免淹没这篇文章,我将只包含运行可执行文件时产生的一小部分输出。
WARNING: ThreadSanitizer: data race (pid=18858)
Write of size 4 at 0x000102ef7d80 by thread T2:
#0 eval_positioning 8q.c:178 (8q:x86_64+0x100003416)
Previous write of size 4 at 0x000102ef7d80 by thread T3:
[failed to restore the stack]
Location is global 'printouts' at 0x000102ef7100 (8q+0x000100008d80)
Thread T2 (tid=3263043, running) created by main thread at:
#0 pthread_create <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2cd8d)
#1 main 8q.c:249 (8q:x86_64+0x1000039c6)
Thread T3 (tid=3263063, running) created by main thread at:
#0 pthread_create <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2cd8d)
#1 main 8q.c:249 (8q:x86_64+0x1000039c6)
SUMMARY: ThreadSanitizer: data race 8q.c:178 in eval_positioning
第 178 行是指以下代码段:
pthread_mutex_lock(&print_mutex);
memcpy(printouts.qpositions[++printouts.top], qpositions, N*sizeof(int));
pthread_mutex_unlock(&print_mutex);
这行代码可以被多个线程访问,因此我实现了一个锁来避免同步问题。这也是整个文件中唯一一次写入该特定共享内存的情况。
typedef struct print_buf {
int qpositions[100][8];
int top;
} print_buf;
print_buf printouts = { {{0}}, -1 };
总而言之,我print_buf
用锁“正确”地保护了结构,但消毒剂抱怨。这实际上将如何成为一场数据竞赛?我错过了什么?