c – 来自std :: set insert()和find()的写入数据竞争?
发布时间:2020-12-16 07:08:07 所属栏目:百科 来源:网络整理
导读:为了试验线程消毒器,我创建了一个微小的C程序,其目的包含数据竞争.确实,tsan确实检测到错误,太棒了!但是我对生成的消息感到困惑…… 它报告了一个写 – 写数据竞赛,我本来期望读写竞赛.我希望find()不会写入我的容器中.如果我尝试进一步调整set :: find()的
为了试验线程消毒器,我创建了一个微小的C程序,其目的包含数据竞争.确实,tsan确实检测到错误,太棒了!但是我对生成的消息感到困惑……
>它报告了一个写 – 写数据竞赛,我本来期望读写竞赛.我希望find()不会写入我的容器中.如果我尝试进一步调整set :: find()的const版本进行进一步的小代码调整,那么相同的写 – 写比赛似乎仍然存在. 是否可以选择使用不写入STL容器的const find()? 这是经过测试的C程序: /***************************************************************************** * Small example with an inter-thread data race that is not obvious. * the error is a consequence of the non-threadsafeness of the STL containers. * Threading is created through portable C++11 constructs. * Tsan does detect the data race(?). * * Compile with one of: * g++-4.8 -std=c++11 -g -Wall -o race-stl11b race-stl11b.cc -pthread * g++-4.8 -std=c++11 -g -Wall -fsanitize=thread -fPIE -o race-stl11b-tsan race-stl11b.cc -ltsan -pie -pthread ******************************************************************************/ #include <iostream> #include <thread> #include <set> int main() { // create an empty bucket std::set<int> bucket; // Use a background task to insert value '5' in the bucket std::thread t([&](){ bucket.insert(5); }); // Check if value '3' is in the bucket (not expected :-) bool contains3 = bucket.find(3) != bucket.cend(); std::cout << "Foreground find done: " << contains3 << std::endl; // Wait for the background thread to finish t.join(); // verify that value '5' did arrive in the bucket bool contains5 = bucket.find(5) != bucket.cend(); std::cout << "Background insert: " << contains5 << std::endl; return 0; } 这是tsan输出(的一部分): WARNING: ThreadSanitizer: data race (pid=21774) Write of size 8 at 0x7d080000bfc8 by thread T1: #0 <null> <null>:0 (libtsan.so.0+0x00000001e2c0) #1 deallocate /usr/include/c++/4.8/ext/new_allocator.h:110 (exe+0x000000002a79) #2 deallocate /usr/include/c++/4.8/bits/alloc_traits.h:377 (exe+0x000000002962) #3 _M_destroy /usr/include/c++/4.8/bits/shared_ptr_base.h:417 (exe+0x00000000306b) #4 <null> <null>:0 (libstdc++.so.6+0x0000000b5f8a) Previous atomic write of size 4 at 0x7d080000bfc8 by main thread: #0 <null> <null>:0 (libtsan.so.0+0x00000000da45) #1 __exchange_and_add /usr/include/c++/4.8/ext/atomicity.h:49 (exe+0x000000001c9f) #2 __exchange_and_add_dispatch /usr/include/c++/4.8/ext/atomicity.h:82 (exe+0x000000001d56) #3 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/4.8/bits/shared_ptr_base.h:141 (exe+0x00000000390d) #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/4.8/bits/shared_ptr_base.h:553 (exe+0x00000000363c) #5 std::__shared_ptr<std::thread::_Impl_base,(__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/4.8/bits/shared_ptr_base.h:810 (exe+0x00000000351b) #6 std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() /usr/include/c++/4.8/bits/shared_ptr.h:93 (exe+0x000000003547) #7 thread<main()::__lambda0> /usr/include/c++/4.8/thread:135 (exe+0x0000000020c3) #8 main /home/......./race-stl11b.cc:22 (exe+0x000000001e38) 感谢您的任何反馈, 解决方法
看起来ThreadSanitizer在std :: thread实现上给你一个误报.
减少您的示例以不执行任何设置操作,如下所示: #include <iostream> #include <thread> #include <set> int main() { std::set<int> bucket; std::thread t([&](){ /*bucket.insert(5);*/ }); t.join(); return 0; } 仍然在ThreadSanitizer中给出相同的错误. 请注意,ThreadSanitizer找不到您的读写竞争条件. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- XML fragments parsed from previous mappers al
- u-boot1.1.6在NorFlash下启动后实现对Nand的操作
- Oracle LONG and LONG RAW Causing “Stream has
- c# – WCF数据服务限制返回字段的能力
- cassandra ::我可以创建一个没有主键的表吗?
- Flex4之控制状态转换以及产生动画特效【登录示例
- ruby-on-rails – Rails 4 collection_check_box
- ajax – 多次订阅rxjs Observer而不执行多个请求
- 苹果推送Swift Playgrounds 2第一个beta
- actionscript-3 – FlashDevelop中的Flex元数据编
热点阅读