0Pricing
C++ Academy · Урок

std::atomic и порядок работы с памятью

Используйте std::atomic с подходящим порядком работы с памятью для корректности и скорости.

«std::atomic и порядок работы с памятью» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

За пределами мьютексов

Блокировки последовательно предоставляют доступ — это просто и надёжно, но они ограничивают пропускную способность. std::atomic предоставляет строительные блоки без блокировок для высокопроизводительного параллельного кода.

Основы std::atomic

std::atomic<T> оборачивает значение и поддерживает атомарные операции чтения, изменения и записи.

#include <atomic>
std::atomic<int> counter{0};
counter.fetch_add(1);    // atomic increment
int v = counter.load();
counter.store(0);

Удобные операторы

Для арифметических типов обычные операторы являются атомарными.

std::atomic<int> n{0};
++n;          // atomic increment
n += 5;        // atomic add
int v = n;     // atomic load

Почему атомарные операции сложны

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

Порядки памяти

Пять распространённых порядков:

  • memory_order_relaxed — атомарность без упорядочивания
  • memory_order_acquire — используется в паре с release; запрет перестановки после операции
  • memory_order_release — используется в паре с acquire; запрет перестановки перед операцией
  • memory_order_acq_rel — оба ограничения
  • memory_order_seq_cst — последовательная согласованность (по умолчанию)

Последовательная согласованность: безопасный вариант по умолчанию

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

Сочетание acquire и release

Используйте release в производителе и acquire в потребителе. После acquire становятся видимыми все записи, выполненные до соответствующего release.

std::atomic<bool> ready{false};
int data = 0;

// producer
data = 42;
ready.store(true, std::memory_order_release);

// consumer
while (!ready.load(std::memory_order_acquire));
std::cout << data;    // sees 42

Ослабленный порядок

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

Сравнение и обмен

Основа большинства алгоритмов без блокировок. compare_exchange_strong(expected, desired) атомарно обновляет значение только в том случае, если текущее значение равно expected.

std::atomic<int> a{10};
int expected = 10;
bool ok = a.compare_exchange_strong(expected, 20);
// if true, a is now 20; otherwise expected holds the actual current value

Слабый и сильный CAS

compare_exchange_weak может ошибочно завершиться неудачей даже при совпадении значений. Используйте его внутри циклов, поскольку на некоторых платформах он эффективнее; вне циклов используйте strong.

Без блокировок и без ожидания

Две гарантии продвижения:

  • Без блокировок — хотя бы один поток в любой момент продвигается
  • Без ожидания — каждый поток продвигается за ограниченное время

Когда использовать атомарные операции

Атомарные операции не всегда быстрее мьютексов. Используйте их, когда критический путь можно сделать простым: для счётчиков, флагов и простых состояний. Для сложного общего состояния мьютексы обычно безопаснее и понятнее.

Быстрая проверка

Какой порядок памяти предоставляет самые сильные гарантии, но при этом является самым медленным?

Итоги

std::atomic предоставляет примитивы без блокировок с явным управлением порядком памяти. По умолчанию выбирайте memory_order_seq_cst; используйте пары acquire/release в шаблонах «производитель — потребитель»; применяйте relaxed только для неупорядоченных атомарных операций, например для счётчиков.

Часто задаваемые вопросы

Урок «std::atomic и порядок работы с памятью» бесплатный?

Да — полный текст урока «std::atomic и порядок работы с памятью» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «std::atomic и порядок работы с памятью»?

Используйте std::atomic с подходящим порядком работы с памятью для корректности и скорости. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «std::atomic и порядок работы с памятью»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. std::atomic и порядок работы с памятью
  2. Сравнение и обмен: шаблоны CAS
  3. Реализация очереди без блокировок
  4. Опасные указатели и проблема ABA
← Назад к C++ Academy