2012-04-23 10 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(); 
} 

を私の知る限りプログラムはOKですが、そのプログラムがレースであってもなくて言います無料)。 しかし、tsanは文句を言って警告を出します: http://www.filedropper.com/output 私はツールを間違って使っていますか、それとも本当に良いのですか? 重要な場合はVS11 Betaを使用しています。

+0

同期がなくてもプログラムは正しいでしょう... –

+0

私はそう思っています。最初に参加すれば十分です。私は確信したかっただけです。 Ofcの2回目の参加が必要です。 – NoSenseEtAl

+0

両方のジョインが必要ですが、それを書いた方法では同時性はありません。 –

答えて

9

これは正常ですが、ThreadSanitizerはC++ 11スレッドライブラリを適切に処理する方法を知らず、Interlocked *またはstd :: atomicを使用してきめ細かな同期を処理できません。さらに、ハイブリッドモードは偽陽性を生成する可能性があります。標準ライブラリのレースやその他の誤検出を無視する抑制ファイルを作成することができます。 Linux x64とThreadSanitizerでコードを使用すると、stdlibに7つの偽りのレースがあります。 suppression fileを追加した後、私はこれらのレースを無視することができました。その後、私はあなたのロックを解除し、2番目のスレッドの開始後にあなたのt1.join()を移動させたので(本当のレースがあります)、ThreadSanitizerはこれを正しく検出します。その後、あなたのミューテックスを追加して、レースはもはや報告されませんでした。だから実際にはかなり役に立つようです。

:それはかなり成熟ですので、(。私のUbuntu 12.10システム上でそれを構築する本当の痛みだったが)Googleは、他の多くのプロジェクトの中で、自分のChromeブラウザでのレースを見つけるためにそれを使用しています

を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

+0

btw私は、C + + 11のサポートを期待していません。 – NoSenseEtAl

+2

プロジェクトサイトでは、ThreadSanitizer 2(LLVMを使用し、x64 linux atmしかサポートしない新しく高速なTSanのバージョン)の短期間のtodoリストにあります。 – Eloff

関連する問題