c++ - Clang ThreadSanitizer : unlock of an unlocked mutex,和一个原子正在创建数据争用

标签 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说互斥锁被“两次”解锁了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
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错了吗?有人可以解释这是怎么回事吗?

最佳答案

我从来没有想过互斥锁问题,但是我可以通过使其他负载成为原子来摆脱与原子的数据争用:

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

关于c++ - Clang ThreadSanitizer : unlock of an unlocked mutex,和一个原子正在创建数据争用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45218847/

相关文章:

c++ - 使用虚拟流操纵器时为 "Error C3867: non-standard syntax; use ' & ' to create a pointer to member"

c++ - 管道标准输出到 Qt 4.7 中的 QLabel

java - Spring、MVC、Java,让单例 bean 每 5 秒执行一次操作?

c# - 是否可以根据条件设置临界区?

大型数据库插入的时间戳之间的 Java 计数

c++ - 使用 std::find_if 时从传递给 lambda 的元素中获取迭代器

c++ - 如何在没有 Singleton 的情况下实现方便的日志记录?

c++ - clang vs gcc - 优化包括 operator new

c++ - 为什么这不违反单一定义规则?

c++ - 如何在 linux 中编译 c++ 程序以生成 windows 可执行文件?