gpt4 book ai didi

c++ - ThreadSanitizer 报告的数据竞争

转载 作者:行者123 更新时间:2023-12-01 14:29:30 29 4
gpt4 key购买 nike

我正在使用启用了线程清理器的 Clang-8 来编译下面的代码

std::atomic<std::string*> ptr {nullptr};
int data {0};

void producer() {
std::string* p = new std::string("Hello");
data = 42;
ptr.store(p, std::memory_order_release);
}

void consumer() {
std::string* p2;
if(!(p2 = ptr.load(std::memory_order_relaxed))) {
// Data is not ready, just return
return ;
}
std::atomic_thread_fence(std::memory_order_seq_cst);
assert(data == 42); // Never fired
}

int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
}

线程清理器报告全局变量 data 上的数据竞争警告。为什么这被认为是数据竞赛?

==================
WARNING: ThreadSanitizer: data race (pid=20388)
Read of size 4 at 0x000001191718 by thread T2:
#0 consumer() <null> (a.out+0x4afe32)
#1 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) <null> (a.out+0x4b1fad)
#2 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) <null> (a.out+0x4b1ee0)
#3 decltype(std::__invoke(_S_declval<0ul>())) std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0x4b1e88)
#4 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null> (a.out+0x4b1e28)
#5 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() <null> (a.out+0x4b1c1c)
#6 <null> <null> (libstdc++.so.6+0xbd66e)

Previous write of size 4 at 0x000001191718 by thread T1:
#0 producer() <null> (a.out+0x4afcca)
#1 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) <null> (a.out+0x4b1fad)
#2 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) <null> (a.out+0x4b1ee0)
#3 decltype(std::__invoke(_S_declval<0ul>())) std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0x4b1e88)
#4 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null> (a.out+0x4b1e28)
#5 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() <null> (a.out+0x4b1c1c)
#6 <null> <null> (libstdc++.so.6+0xbd66e)

Location is global 'data' of size 4 at 0x000001191718 (a.out+0x000001191718)

Thread T2 (tid=20391, running) created by main thread at:
#0 pthread_create <null> (a.out+0x424775)
#1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xbd924)
#2 main <null> (a.out+0x4afec1)

Thread T1 (tid=20390, finished) created by main thread at:
#0 pthread_create <null> (a.out+0x424775)
#1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xbd924)
#2 main <null> (a.out+0x4afeae)

SUMMARY: ThreadSanitizer: data race in consumer()
==================
ThreadSanitizer: reported 1 warnings

更新

我已阅读Why does ThreadSanitizer report a race with this lock-free example?并使用 Clang-8 编译代码。它不显示任何数据竞争警告。所以我认为我的情况有所不同。

最佳答案

您的示例在将 42 存储到数据和写入数据值之间没有同步。编译器可以自由地在生产者中重新排序这两个,这意味着即使在屏障和检查之后数据的值也是未定义的。

关于c++ - ThreadSanitizer 报告的数据竞争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57983170/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com