第 25 集:由 Victor Costan 於 SFO (2021 年 10 月)
上集節目
在 C++ 中,我們會針對每種資料成員存取權,進行小型執行緒安全正確性的驗證,排除資料競爭的可能性。這些證明構成了大量神經作業,特別是在審查或重構程式碼時。Clang 的靜態分析架構可接手確保執行緒安全。
將 GUARDED_BY_CONTEXT()
新增至執行緒不安全的類別中的資料成員
大部分的 Chrome 類別都屬於不安全的執行緒,且應用於單一序列。為所有不安全的資料成員新增註解。不必要的註解安全無虞,但缺少註解可能會造成資料競爭。
#include "base/sequence_checker.h" // for SEQUENCE_CHECKER()
#include "base/thread_annotations.h" // for GUARDED_BY_CONTEXT()
class Cache {
// Methods here.
private:
SEQUENCE_CHECKER(sequence_checker_);
base::flat_map<std::string, std::string> data_ GUARDED_BY_CONTEXT(sequence_checker_);
};
Clang 會強制執行序列檢查
為了傳回將資料成員加上註解的情況,Clang 會確保存取該資料的任何方法會先執行序列安全檢查,然後再這麼做。當程式碼在重構中移動時,Clang 會繼續強制執行 GUARDED_BY_CONTEXT()
註解。
void Cache::Set(base::StringPiece key, base::StringPiece value) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Clang warns without this.
data_.emplace(key, value);
}
將 GUARDED_BY()
新增至使用互斥鎖的執行緒安全類別中的資料成員
在 Chrome 中,部分類別必須使用鎖定來確保執行緒安全。 在這類情況下,請為所有不安全的資料成員加上註解。每個註解都指向一個在存取資料成員時必須保留的互斥鎖。
#include "base/thread_annotations.h" // for GUARDED_BY()
class ThreadSafeCache {
// Methods here.
private:
base::Lock lock_;
base::flat_map<std::string, std::string> data_ GUARDED_BY(lock_);
};
Clang 強制執行鎖定獲取新客
請稍待,讓編譯器確保每個 base::AutoLock
都已正確限定範圍,並正確鎖定 Acquire()
和 Release()
呼叫。
void ThreadSafeCache::Set(base::StringPiece key, base::StringPiece value) {
base::AutoLock auto_lock(lock_); // Clang warns without this.
data_.emplace(key, value);
}
- Chrome 的執行緒和工作
- Clang Thread 安全分析:瞭解其他更複雜的 Clang 註解。