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

Должен ли я явным образом называть атомную нагрузку/хранилище?

В С++ 11 была представлена ​​библиотека шаблонов std::atomic<>. Стандарт определяет операции store() и load() для атомарного набора/получения переменной, разделяемой более чем одним потоком.

Мой вопрос в том, что операции присваивания и доступа также являются атомарными?

А именно:

std::atomic<bool> stop(false);
...
void thread_1_run_until_stopped()
{
    if(!stop.load())
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop.store(true);
}

Эквивалент:

void thread_1_run_until_stopped()
{
    if(!stop)
        /* do stuff */
}

void thread_2_set_stop()
{        
    stop = true;
}
4b9b3361

Ответ 1

Являются ли операции присваивания и доступа для не ссылочных типов атомарными?

Да, они есть. atomic<T>::operator T и atomic<T>::operator= эквивалентны atomic<T>::load и atomic<T>::store соответственно. Все операторы реализованы в атомном классе, так что они будут использовать атомные операции, как и следовало ожидать.

Я не уверен, что вы имеете в виду о типах "без ссылки"? Не знаете, какие ссылочные типы имеют значение здесь.

Ответ 2

Вы можете сделать обоим, но преимущество load()/store() заключается в том, что они позволяют указывать порядок памяти. Иногда это важно для производительности, где вы можете указать std::memory_order_relaxed, в то время как atomic<T>::operator T и atomic<T>::operator= будут использовать наиболее безопасный и медленный std::memory_order_seq_cst. Иногда это важно для правильности и удобочитаемости вашего кода: хотя по умолчанию std::memory_order_seq_cst наиболее безопасен, поэтому, скорее всего, он будет правильным, для читателя не сразу понятно, какую операцию (приобретать/выпускать/потреблять) вы делаете, или выполняете ли вы вообще такую ​​операцию (чтобы ответить: не достаточно ли здесь порядок порядка?).