Folge 25:von Victor Costan auf SFO (Oktober 2021)
Vorherige Folgen
Wenn in C++ mögliche Datenrennen ausgeschlossen werden, reicht ein kleiner Nachweis der Threadsicherheit bei jedem Datenzugriff aus. Diese Beweise bedeuten eine Menge Arbeit, insbesondere bei der Überprüfung oder Refaktorierung von Code. Das statische Analyse-Framework von Clang übernimmt die mühsame Arbeit von Beweisen zur Threadsicherheit.
GUARDED_BY_CONTEXT()
zu Datenmitgliedern in Threads-unsicheren Klassen hinzufügen
Die meisten Chrome-Klassen sind nicht sicher und sollten für eine einzelne Sequenz verwendet werden. Fügen Sie allen Datenmitgliedern, die nicht Thread-sicher sind, Annotationen hinzu. Unnötige Anmerkungen sind sicher. Fehlende Annotationen führen jedoch zu Datenrennen.
#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 erzwingt Sequenzprüfungen
Als Annotierung der Datenelemente sorgt Clang dafür, dass jede Methode, die auf die Daten zugreift, vorher eine Sequenzsicherheitsprüfung durchführt. Wenn der Code im Rahmen von Refaktorierungen verschoben wird, erzwingt Clang weiterhin die Annotation 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()
zu Datenmitgliedern in Thread-sicheren Klassen hinzufügen, die Mutexe verwenden
Einige Klassen in Chrome müssen Sperren für die Threadsicherheit verwenden. Annotieren Sie in diesen Fällen alle Datenmitglieder, die nicht Thread-sicher sind. Jede Annotation verweist auf einen Mutex, der beim Zugriff auf das Datenmitglied gehalten werden muss.
#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 erzwingt das Abrufen von Sperren
Warten Sie einen Moment und lassen Sie den Compiler prüfen, ob jeder base::AutoLock
-Bereich korrekt begrenzt ist und ob Sperraufrufe Acquire()
und Release()
korrekt gekoppelt sind.
void ThreadSafeCache::Set(base::StringPiece key, base::StringPiece value) {
base::AutoLock auto_lock(lock_); // Clang warns without this.
data_.emplace(key, value);
}
- Threading und Tasks in Chrome
- Clang-Thread-Sicherheitsanalyse: Hier erfährst du mehr über andere Clang-Annotationen für komplexere Szenarien.