Подтвердить что ты не робот

Инициализация std:: atomic_bool?

Я хочу использовать std::atomic_bool, потому что хочу иметь логическое значение, которое должно быть доступно для разных потоков.

Это переменная a static. Проблема в том, что я хочу инициализировать ее с помощью false в качестве первого состояния. Обычно я делал это так: std::atomic_bool World::mStopEvent = false;

Но проблема заключается в том, что в качестве конструктора не требуется false. Итак, как я должен инициализировать такую ​​переменную? Я использую VS 2012.

4b9b3361

Ответ 1

Это известная проблема в Visual Studio 2012 (известная как VC11), вы должны проголосовать за существующий элемент Connect, чтобы Microsoft знала, что это влияет на большее количество людей, поскольку они 'отложил исправление.

Привет,

Спасибо за сообщение об этой ошибке. Я являюсь сторонником STL в Microsoft, и я хотел сообщить вам, что, хотя эта ошибка остается активной в нашей базе данных, она не будет исправлена ​​в RTM VC11 (RTM RT). Все ошибки важны для нас, но некоторые из них более серьезны, чем другие, и поднимаются на вершину нашей очереди приоритетов.

Я копирую и вставляю этот ответ по всем ошибкам подключаемого модуля STL, но следующие краткие комментарии относятся конкретно к вашей ошибке:

  • Да, эти конструкторы отсутствуют на atomic_bool, atomic_int и т.д. (atomic<bool>, atomic<int> и т.д.). 29.5 [atomics.types.generic]/7 говорит: "Должны быть названы типы, соответствующие интегральным специализациям атома, как указано в таблице 145, и именованный тип atomic_bool, соответствующий указанному atomic<bool>. Каждый именованный тип a либо typedef к соответствующей специализации или базовому классу соответствующей специализации. Если это базовый класс, он должен поддерживать те же функции-члены, что и соответствующая специализация". который заставляет меня действительно хотеть использовать typedefs (1 тип всегда проще, чем 2 типа), но мне нужно будет увидеть, не приведет ли это к каким-либо другим проблемам.

Я не могу обещать, когда мы сможем решить эту ошибку, но мы надеемся сделать это как можно скорее (и я пришлю еще один ответ, когда это произойдет) - наша первая возможность будет "вне" диапазона "между VC11 и VC12, о которых объявил Herb Sutter на конференции GoingNative 2012.

Примечание. Connect не уведомляет меня о комментариях. Если у вас есть дополнительные вопросы, напишите мне по электронной почте.

Стефан Т. Лававей Старший разработчик - библиотеки Visual С++ [email protected]

В принципе, вам нужно будет использовать std::atomic<T>.

Ответ 2

Проблема:

Вы не можете использовать инициализацию копирования, потому что std::atomic_bool не имеет возможности для копирования:

std::atomic_bool World::mStopEvent = false; // ERROR!

На самом деле, приведенное выше эквивалентно:

std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!

Однако вы можете использовать прямую инициализацию:

std::atomic_bool World::mStopEvent(false);

По вашему желанию вы можете использовать скобки вместо круглых скобок:

std::atomic_bool World::mStopEvent{false};

Ошибка:

В то время как инициализация копирования является незаконной независимо от того, какой вы выбираете, кажется, что реализация стандартной библиотеки, поставляемой с VC11, имеет ошибку, которая также не позволяет выполнять прямую инициализацию.

Итак, как я должен инициализировать такую ​​переменную?

Временное решение:

В качестве возможного обходного пути вы можете предоставить пару статических обмоток getter/setter, которые - соответственно - устанавливают и возвращают значение атомного логического флага, но не перед тем, как убедиться, что он был инициализирован хотя бы один раз и не более один раз до желаемого начального значения в потокобезопасной манере (вы можете рассмотреть эту некоторую ленивую инициализацию):

#include <atomic>
#include <mutex>

struct World
{
    static bool is_stop_event_set()
    {
        std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; });
        return mStopEvent;
    }

    static void set_stop_event(bool value)
    {
        std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; });
        mStopEvent = value;
    }

    static std::atomic_bool mStopEvent;
    static std::once_flag mStopEventInitFlag;
};

std::atomic_bool World::mStopEvent;
std::once_flag World::mStopEventInitFlag;

Теперь вместо прямого доступа к mStopEvent его значение должно быть прочитано через функцию is_stop_event_set():

#include <iostream>

int main()
{
    std::cout << World::is_stop_event_set(); // Will return false
}

Ответ 4

Как насчет:

std::atomic_bool World::mStopEvent(false);