我想过试用线程清理程序(http://code.google.com/p/data-race-test/wiki/ThreadSanitizer#Using_ThreadSanitizer) 所以我做了一个简单的程序:
#include <thread>
#include <atomic>
#include <vector>
#include <iostream>
#include <algorithm>
#include <mutex>
using namespace std;
int violated=0;
mutex mtx;
void violator()
{
lock_guard<mutex> lg(mtx);
violated++;
}
int main()
{
thread t1(violator);
t1.join();
thread t2(violator);
t2.join();
}
AFAIK程序没问题,因为违反的访问权限与互斥锁同步(并且评论说即使没有该程序也没有竞争)。 但是tsan抱怨并发出一堆警告: http://www.filedropper.com/output 我使用该工具是错误的,还是不是很好? 如果重要,我正在使用VS11 Beta。
答案 0 :(得分:11)
这是正常的,ThreadSanitizer不知道如何正确处理C ++ 11线程库,它也无法使用Interlocked *或std :: atomic处理细粒度同步。此外,混合模式可能产生误报。您可以构建一个抑制文件来忽略标准库中的种族和其他误报。在linux x64和ThreadSanitizer上使用你的代码我在stdlib中得到了7个错误的比赛。添加suppression file后,我可以忽略这些比赛。然后我删除了你的锁并在第二个线程开始之后将你的t1.join()移动到了(所以有一个真正的竞争。)ThreadSanitizer正确检测到这一点。然后我重新加入你的互斥体,不再报告比赛。所以它确实看起来非常有用。谷歌使用它在Chrome浏览器和许多其他项目中找到比赛,所以它已经相当成熟(尽管在我的ubuntu 12.10系统上构建它真的很痛苦。)
对于linux,我的抑制文件如下:
{
<std::shared_ptr>
ThreadSanitizer:Race
...
fun:std::_Sp_counted_base::_M_release
fun:std::__shared_count::~__shared_count
fun:std::__shared_ptr::~__shared_ptr
}
{
<std::arena_thread_freeres>
ThreadSanitizer:Race
fun:arena_thread_freeres
fun:__libc_thread_freeres
fun:start_thread
}