Clang ThreadSanitizer:解锁未锁定的互斥锁,原子正在创建数据争用

时间:2017-07-20 15:16:39

标签: c++ multithreading c++11 thread-safety thread-sanitizer

我正在使用ThreadSanitizer进行线程分析,并且我收到的警告非常非常混淆了我对互斥体如何工作的理解。我在Debian Stretch上使用gcc 6.3。

在一个课程中,在一个帖子中,我有:

auto MyPtr = std::make_shared<MyClass>(...);

在另一个被另一个线程调用的地方,我有:

if(MyPtr.get()) {...}

ThreadSanitizer警告我一个竞争条件,这很棒。所以我通过以下方法解决了这个问题:

std::unique_lock<decltype(MyMutex)> lg(MyMutex); //MyMutex is std::mutex
auto MyPtr = std::make_shared<...>(...);
lg.unlock();

另一个地方:

std::unique_lock<decltype(MyMutex)> lg(MyMutex);
if(MyPtr.get()) {...}
// mutex unlocks at the end of the function, which is like after another if-condition.

现在数据竞争已经消失,ThreadSanitizer说Mutex正在“解锁”两次......

WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread)

它指向unlock()调用+另一个函数的结束。

如何将互斥锁解锁两次?有人可以解释一下吗?

现在既然这让我很头疼,我决定这样做:

std::shared_ptr<MyClass> MyPtr; //in the class definition
std::atomic_store(&MyPtr, std::make_shared<MyClass>(...));

现在我收到了数据竞争投诉:

WARNING: ThreadSanitizer: data race

我使用ThreadSanitizer是错误的吗?有人能解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:0)

我从来没有弄清楚互斥问题,但我能够通过使其他负载原子化来摆脱原子的数据竞争:

if(std::atomic_load(&MyPtr).get()) {...}