2016-11-07 102 views
1

我有以下互斥類(希望)在鏗鏘線程安全模型後實現。 (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)是否正確?如果是的話,違規事件究竟發生了什麼?

回答

-1

此代碼非常有問題。您從unique_lock繼承,但您沒有正確構建它!您擁有自己的互斥鎖,可以鎖定/解鎖,但unique_lock擁有的互斥鎖將保持未初始化狀態。條件變量wait_for將在父鎖上調用release,並釋放解鎖的互斥鎖,從而將互斥鎖鎖定。

我沒有看到任何理由參與這個在您的自定義類中重新實現鎖定的練習。請記住,標準庫類幾乎是永遠不會意味着要繼承。

+0

我們需要與幾個編譯器和不同的stdlib之間進行編譯。然而只有clang在它自己的lib中提供了這個功能。因此我們需要在我們自己的代碼中重新實現它。 – Trevir

+0

比你需要重新實現幾乎所有東西。你不能像你那樣繼承它。 – SergeyA

+0

我已經相應地更改了代碼,警告保持不變。請更詳細地說明繼承不適合的原因。 – Trevir

1

因爲編譯器不清楚,在哪裏計算lambda表達式,所以還需要註釋lambda。

正確的路線,這不會產生任何錯誤是

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