Предотвращает ли std :: atomic переупорядочение неатомарных переменных над атомарными переменными - PullRequest
3 голосов
/ 09 января 2012

вопрос довольно прост В: Если у меня есть

settings[N_STNGS];//used by many threads  
std::atomic<size_t> current_settings(0);
void updateSettings()//called by single thread  , always the same thread if that is important
{

    auto new_settings = (current_settings+1)%N_STNGS;
    settings[new_settings].loadFromFileSystem(); //line A
    current_settings=new_settings; //line B
}

, гарантирует ли стандартная строка, что строка A не будет переупорядочена после строки B?Кроме того, будут ли пользователи STNGS всегда видеть непротиворечивые (зафиксированные, как в видимости памяти видимые) данные?

Редактировать: для нескольких потоков считывателей и нетривиальных настроек стоит ли эта проблема по сравнению с простым мьютексированием?

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Учитывая определение

int settings[N_STNGS];
std::atomic<size_t> current_settings(0);

и выполнение потока 1:

settings[new_settings] = somevalue;  // line A
current_settings=new_settings;       // line B

и выполнение потока 2:

int cur_settings = current_settings;        // line X
int setting_value = settings[cur_settings]; // line Y

тогда да, если поток 2 в строке X читает new_settings, записанный потоком 1 в строке B, и нет других модификаций settings[new_settings] (по какому-то коду, которого мы не видим), поток 2 связан с прочитайте somevalue, и не произойдет неопределенного поведения. Это происходит потому, что все операции (по умолчанию) memory_order_seq_cst, а запись-отпускание (строка B) синхронизируется с операцией-чтение-чтение (строка X). Обратите внимание, что вам нужны два оператора в потоке 2, чтобы получить последовательность перед последовательностью между атомарным чтением индекса и чтением значения (вместо этого подойдет операция memory_order_consume).

Я бы наверняка реализовал это с помощью rw-mutexes для запуска.

0 голосов
/ 09 января 2012

Общий ответ - нет. Если вы осторожны и используете только те функции, которые имеют параметр memory_order и передают им правильное значение в зависимости от того, что вы делаете, тогда это может быть да.

(И, как уже отмечалось, у вашего кода есть проблемы. Например, возвращение по значению атомарного типа <> не имеет смысла для меня.)

...