- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
为了试验线程清理器,我创建了一个微型 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 不会找到您的读写竞争条件。
关于c++ - 来自 std::set insert() 和 find() 的写-写数据竞争?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22252399/
假设我正在使用 APC,其中过程和调用代码都使用 SetLastError 和 GetLastError。这会导致 GetLastError 产生不可预测的值。有什么办法可以解决这个问题吗? VOID
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 7年前关闭。 Improve t
任何人都可以,请告诉我,如何在不进行JavaScript轮询/ setInterval的情况下,在完整日历上填充/显示在服务器端动态更新的数据。 grails中提供了Atmosphere插件,但是文档
我正在尝试调整我的代码,从仅在前台使用 WCSessionDelegate 回调到在后台通过 handleBackgroundTasks: 接受 WKWatchConnectivityRefreshB
我正在构建批处理系统。 单位 的批处理数量从 20 到 1000 不等。每个 Unit 本质上都是模型的层次结构(一个主模型和许多子模型)。我的任务涉及将每个模型层次结构作为单个事务保存到数据库中(每
我拍了一张图片并将其切成三 block ,然后将它们向右浮动,让文字围绕它们流动。 HTML 看起来像这样: 在我添加侧边栏并将其 float 到图像的右上方之前,它工作正常,就像这样... T
我正在考虑嵌入式 Linux 项目(还没有硬件)中即将出现的情况,其中两个外部芯片需要共享一条物理 IRQ 线。这条线在硬件中能够实现边沿触发,但不能实现电平触发中断。 查看 Linux 中的共享 i
我观察到,当 linux futexes 发生争用时,系统会在自旋锁上花费大量时间。我注意到即使不直接使用 futex 也是一个问题,但在调用 malloc/free、rand、glib 互斥调用和其
我终于能够获得一些工具提示,最终可以使用以下代码: Hover over me 然后 $('[rel=tooltip]').tooltip(); 我遇到的问题是它使用 jQueryUI 工
我是一名优秀的程序员,十分优秀!