выше ли это правда?
Да. Если вы не используете синхронизацию (std::atmoic<>
, std::mutex
, ...), то любые изменения, сделанные вами в одном потоке, не могут быть обнаружены в других потоках. Может даже быть, что компилятор что-то оптимизирует, потому что нет никакой возможности изменить его функцию. Например
bool flag = true;
void stop_stuff()
{
flag = false;
}
void do_stuff()
{
while (flag)
std::cout << "never stop";
}
, поскольку для flag
нет синхронизации, компилятор может предположить, что он никогда не изменится optmize, даже проверяя флаг в условии цикла. Если это произойдет, то независимо от того, сколько раз вы звоните stop_stuff
, do_stuff
никогда не закончится.
Если вы измените флаг на std::atomic<bool> flag
, то компилятор больше не может делать такое предположение, поскольку вы говорите ему, что эта переменная может изменяться вне области действия функции, и ее необходимо проверить.
Обратите внимание, что отсутствие синхронизации, когда у вас есть более одного потока с общими данными, и хотя бы один из этих потоков выполняет запись в общие данные, называется гонкой данных, и в соответствии со стандартом это неопределенное поведение. Приведенный выше пример является лишь одним из возможных последствий этого неопределенного поведения.
std::atomic<int64_t> i; i.store(100, std::memory_order_relaxed)
является атомным. так какая магия используется атомами, чтобы это произошло на основе Q1, верно?
Либо использует атомарный примитив, который предоставляет ваша система, либо использует механизм блокировки, например std::mutex
, для защиты доступа.
Я всегда думаю, что любая операция, которая обрабатывает менее 64 бит, является атомарной (предположим, 64-битный процессор), похоже, я ошибался. так что для v = n, как я могу узнать, атомное оно или нет? например, если v void *, это атомарно или нет?
Хотя это может быть верно для некоторых систем, это не так для модели памяти C ++. Единственные атомарные вещи - это std::atomic<T>
.