2012-04-23 19 views
4

我想到的嘗試線程消毒劑(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程序是OK(和評價,比如說,即使沒有該程序是種族自由)。 但燦抱怨,並給出了一堆警告: http://www.filedropper.com/output 所以我使用的工具不對,或者是不是真的好? 如果重要我使用VS11測試版。

+0

即使沒有任何同步,程序也是正確的...... – 2012-04-23 02:37:29

+0

我猜想是這樣,我想第一次加入就夠了......我只是想確定一下。 Ofc第二次加入是必要的。 – NoSenseEtAl 2012-04-23 02:47:32

+0

這兩個連接都是需要的,但是您寫入的方式沒有併發性。 – 2012-04-23 03:05:04

回答

9

這是正常的,ThreadSanitizer不知道如何處理正確地與C++ 11線程庫,也可以不使用互鎖*或std ::原子處理細粒度的同步。此外,混合模式可能會產生誤報。您可以構建一個壓縮文件來忽略標準庫中的競爭和其他誤報。在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 
} 
+0

非常好的答案 – NoSenseEtAl 2012-10-31 08:51:02

+0

btw我不期望C++ 11支持很快,因爲* ing谷歌代碼標準不允許C++ 11。 – NoSenseEtAl 2012-10-31 11:07:13

+2

在他們的項目網站上,它是ThreadSanitizer 2的短期待辦事項列表(使用LLVM的TSan的新的更快版本,但僅支持x64 linux atm。) – Eloff 2012-10-31 15:15:38