【问题标题】:Clang thread safety with std::condition variable带有 std::condition 变量的 Clang 线程安全
【发布时间】:2016-11-08 17:35:48
【问题描述】:

我在 clang 线程安全模型之后实现了以下互斥类(希望如此)。 (http://clang.llvm.org/docs/ThreadSafetyAnalysis.html)

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)是否正确?如果是,违规行为究竟是如何发生的?

【问题讨论】:

    标签: c++ thread-safety clang++


    【解决方案1】:

    因为编译器不清楚 lambda 表达式在哪里求值,所以也有必要对 lambda 进行注释。

    不产生任何错误的正确行是

    return cv_.wait_for( lock, duration, [this]() REQUIRES( mutex_ ) { return count_ >= min_count_; } ); 
    

    【讨论】:

      【解决方案2】:

      这段代码非常有问题。您继承自 unique_lock,但您没有正确构建它!您有自己的互斥锁,可以锁定/解锁,但unique_lock 拥有的互斥锁将保持未初始化状态。条件变量wait_for 将在父锁上调用release,并释放未锁定的互斥体,使您的互斥体保持锁定状态。

      我认为没有任何理由参与这种在您的自定义类中重新实现锁定的练习。请记住,标准库类几乎从不要继承自。

      【讨论】:

      • 我们需要使用多个编译器和不同的标准库进行编译。然而,只有 clang 在它自己的库中提供了这个功能。因此我们需要在自己的代码中重新实现它。
      • 比你必须重新实现几乎所有东西。你不能像以前那样继承它。
      • 我已经相应地更改了代码,警告保持不变。请更详细地说明为什么不适合继承。
      猜你喜欢
      • 2021-08-13
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多