Эпизод 25: Виктор Костан в SFO (октябрь 2021 г.)
Предыдущие серии
В 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 . Узнайте о других аннотациях Clang для более сложных сценариев.