View in Telegram
Безымянный lock_guard Бывает иногда, что при определение объекта забываешь что-то написать. Параметры конструктора, шаблонный параметр класса, точка с запятой - всякое бывает. Такое обычно спокойно детектируется на этапе компиляции и без проблем исправляется. Но вот есть одна "забывашка", которая может привести к действительно неприятным последствиям и не так просто детектируется. Пишите вы такие критическую секцию. Например, просто хотите потокобезопасно обновить мапу. Как полагается в книжках, используете std::lock_guard, но забываете одну деталь.
// std::map<std::string, std::string> SomeClass::map_;
// std::mutex SomeClass::mtx_;

bool SomeClass::UpdateMap(const std::string& key, const std::string& value) {
    std::lock_guard{mtx_};
    auto result = map_.insert({key, value});
    return result.second;
}
Для С++17 вполне синтаксически верный код. И он будет запускаться. Но потокобезопасности не будет. "Но как же! Я же использовал lock_guard!" Да вот только этот lock_guard безымянный. То есть является временным объектом. Соответственно, его деструктор вызовется ровно до insert'а и мьютекс освободится. А значит ничего безопасного тут нет. Мапа будет теперь постоянно в неконсистентном состоянии и удачи потом в поиске этого места, особенно с замыленным глазом. Вроде банальная ошибка. На работе ее еще можно через ревью отловить. Но на пет-проектах или собесах даже опытные люди ее совершают. Так что будьте бдительны в следующий раз и будет вам многопоточное счастье! Stay alerted. Stay cool. #cppcore
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Love Center - Dating, Friends & Matches, NY, LA, Dubai, Global
Find friends or serious relationships easily