exponenta event banner

Атомарная переменная, доступная дважды в выражении

Переменная может быть изменена между доступами

Описание

Этот дефект возникает, когда атомные типы C или C++ std::atomic переменные класса появляются дважды в выражении и существуют:

  • Две операции атомарного считывания для переменной.

  • Операция атомарного чтения и отдельная операция атомарной записи для переменной.

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

Риск

Поток может изменить атомарную переменную между двумя атомарными операциями, что может привести к условию гонки данных.

Зафиксировать

Не ссылайтесь на атомарную переменную дважды в одном выражении.

Примеры

развернуть все


#include <stdatomic.h>

atomic_int n = ATOMIC_VAR_INIT(0);

int compute_sum(void)
{
    return n * (n + 1) / 2;
}

В этом примере глобальная переменная n дважды упоминается в операторе возврата compute_sum(). Значение n может изменяться между двумя различными операциями чтения. compute_sum() может возвращать неверное значение.

Коррекция - передать переменную как аргумент функции

Одной из возможных корректировок является передача переменной в качестве аргумента функции. n. Переменная копируется в память, и операции чтения с копированием гарантируют, что compute_sum() возвращает правильный результат. При передаче переменной типа int вместо типа atomic_int, исправление по-прежнему является действительным.


#include <stdatomic.h>

int compute_sum(atomic_int n)
{
    return n * (n + 1) / 2;
}

Информация о результатах

Группа: Параллелизм
Язык: C | C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: ATOMIC_VAR_ACCESS_TWICE
Воздействие: среднее
Представлен в R2018b