铿锵线程安全与std ::条件变量
问题描述:
我有以下互斥类(希望)在铿锵线程安全模型后实现。 (http://clang.llvm.org/docs/ThreadSafetyAnalysis.html)铿锵线程安全与std ::条件变量
class CAPABILITY("mutex") Mutex : public std::mutex
{
public:
void lock() ACQUIRE()
{
std::mutex::lock();
}
void unlock() RELEASE()
{
std::mutex::unlock();
}
};
class SCOPED_CAPABILITY LockGuard : public std::unique_lock<std::mutex>
{
public:
LockGuard(Mutex& mu) ACQUIRE(mu) : std::unique_lock<std::mutex>(mu)
{
}
~LockGuard() RELEASE()
{
}
};
的用法如下:
class Barrier
{
...
Mutex mutex_;
std::condition_variable cv_ GUARDED_BY(mutex_);
std::size_t min_count_ GUARDED_BY(mutex_);
std::size_t count_ GUARDED_BY(mutex_);
bool Barrier::waitFor(const std::chrono::microseconds& duration)
{
LockGuard lock(mutex_);
if (count_ >= min_count_)
{
return true;
}
else
{
// WARNING IS IN THE LINE BELOW
return cv_.wait_for(lock, duration, [this]() { return count_ >= min_count_; });
}
}
};
我得到铛警告: warning: reading variable 'count_' requires holding mutex 'mutex_' [-Wthread-safety-analysis]
。
编译器的警告(带有-Wthread-safety的clang 3.8)是否正确?如果是的话,违规事件究竟发生了什么?
答
此代码非常有问题。您从unique_lock
继承,但您没有正确构建它!您拥有自己的互斥锁,可以锁定/解锁,但unique_lock
拥有的互斥锁将保持未初始化状态。条件变量wait_for
将在父锁上调用release
,并释放解锁的互斥锁,从而将互斥锁锁定。
我没有看到任何理由参与这个在您的自定义类中重新实现锁定的练习。请记住,标准库类几乎是永远不会意味着要继承。
答
因为编译器不清楚,在哪里计算lambda表达式,所以还需要注释lambda。
正确的路线,这不会产生任何错误是
return cv_.wait_for(lock, duration, [this]() REQUIRES(mutex_) { return count_ >= min_count_; });
我们需要与几个编译器和不同的stdlib之间进行编译。然而只有clang在它自己的lib中提供了这个功能。因此我们需要在我们自己的代码中重新实现它。 – Trevir
比你需要重新实现几乎所有东西。你不能像你那样继承它。 – SergeyA
我已经相应地更改了代码,警告保持不变。请更详细地说明继承不适合的原因。 – Trevir