【问题标题】:Is Thread Sanitizer usable?Thread Sanitizer 可以使用吗?
【发布时间】:2012-04-23 02:15:15
【问题描述】:

我想试试线程消毒剂 (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 程序没问题,因为对违反的访问与互斥锁同步(就像 cmets 说的那样,即使没有该程序也是无种族的)。 但是 tsan 抱怨并给出了一堆警告: http://www.filedropper.com/output 那么我使用该工具是错误的,还是它不是很好? 如果重要的话,我正在使用 VS11 Beta。

【问题讨论】:

  • 即使没有任何同步,程序也是正确的......
  • 我猜是这样,我想第一次加入就足够了……我只是想确定一下。需要 Ofc 第二次加入。
  • 两个连接都是需要的,但是你写它的方式没有并发。
  • 我知道,首先我尝试只拥有一个稍后加入的线程向量,因此有一个 RC,它给出了应有的警告,但后来我决定尝试正常的非 RC 案例.

标签: c++ race-condition


【解决方案1】:

这很正常,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
}

【讨论】:

  • 顺便说一句,我不希望很快支持 C++11,因为 *ing google 代码标准不允许 C++11。
  • 在他们的项目网站上,它位于 ThreadSanitizer 2(使用 LLVM,但仅支持 x64 linux atm 的新的、更快的 TSan 版本)的短期待办事项列表中。
  • 很酷,虽然在看到这个之后:chromium.org/developers/testing/threadsanitizer-tsan-v2 看起来不可能没有问题地让它运行。 :D
猜你喜欢
  • 2016-01-05
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多