Задать вопрос
@tty6

Является ли статическая функция С++ потокобезопасной?

static inline Settings& applicationSettings(){
    if (!File::exists(settingsFilePath)){
        static Settings set(settingsFilePath);
        set.initializeDefaults();
        return set;
    }else{
        static Settings set(settingsFilePath);
        return set;
    }
}


Является ли вызов данной функции потокобезопасным?
Выполняется ли проверка File()::exists(settingsFilePath) при каждом обращении к функции, если функция exists - статична.
  • Вопрос задан
  • 418 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
@MiiNiPaa
Сделайте фабричную функцию проверяющую существование файла и создающее его если надо и затем:
static inline Settings& applicationSettings()
{
    static Settings set = getSettings(settingsFilePath);
    return set;
}
Cтандарт C++11 гарантирует, что getSettings будет вызвана только один раз вне зависимости от количества потоков дёргающих applicationSettings. Главное не забывайте что getSettings не потокобезопасна и не дёргайте её напрямую.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
1. На что вам две статических переменных set?
2. Не забудь, переменная статическая и находится в сегменте данных. Так что конструктор Settings() будет выполнен перед запуском main.
3. Функция возвращает ссылку без const. Будут ли меняться настройки? Да — опасно почти гарантированно (структуры данных, потокобезопасные по записи — дело редкое и сложное). Нет — возвращай const Settings& и убедись, что все поля Settings также потокобезопасны по чтению (обычно ответ на этот вопрос да).
4. А initializeDefaults() потокобезопасен? Скорее всего, нет.

> Является ли вызов данной функции потокобезопасным?
Нет однозначного ответа, скорее всего, нет.

> Выполняется ли проверка File()::exists(settingsFilePath) при каждом обращении к функции?
Выполняется.

ЗЫ. Функция вот такого типа точно потокобезопасна — в ней просто нет объектов, за которые можно устраивать гонку.
static inline Settings applicationSettings(){
    if (!File::exists(settingsFilePath)){
        Settings set(settingsFilePath);
        set.initializeDefaults();
        return set;
    }else{        
        return Settings(settingsFilePath);
    }
}
Ответ написан
Комментировать
Nipheris
@Nipheris Куратор тега C++
С чего бы этому вызову быть потокобезопасным, если у вас в функции статические переменные?
Выполняется ли проверка File()::exists(settingsFilePath) при каждом обращении к функции

А почему она не должна выполняться?

Кстати, а зачем вам две разные статические переменные set?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы