Класс atomic
Класс atomic из заголовочного файла <atomic>
предназначен для выполнения атомарных операций над данными.
Атомарная операция - это операция, которая выполняется
как единое целое и не может быть прервана другим потоком.
Это позволяет безопасно работать с общими данными из
нескольких потоков без использования мьютексов.
В качестве параметра шаблона указывается тип данных,
например int, bool или указатель.
Синтаксис
#include <atomic>
std::atomic<T> name;
std::atomic<T> name(initial);
Пример
Давайте создадим атомарную переменную типа int
и выполним простейшие операции чтения и записи:
#include <iostream>
#include <atomic>
using namespace std;
int main()
{
atomic<int> a(10);
cout << a.load() << endl;
a.store(25);
cout << a.load() << endl;
return 0;
}
Результат выполнения кода:
10
25
Пример
Атомарные переменные поддерживают привычные операторы инкремента, декремента и присваивания:
#include <iostream>
#include <atomic>
using namespace std;
int main()
{
atomic<int> a(1);
a++;
a += 10;
cout << a << endl;
return 0;
}
Результат выполнения кода:
12
Пример
Давайте посмотрим, как atomic помогает
избежать гонки данных. Запустим два потока,
каждый из которых увеличит счётчик 100000 раз:
#include <iostream>
#include <atomic>
#include <thread>
using namespace std;
atomic<int> counter(0);
void increment()
{
for (int i = 0; i < 100000; i++) {
counter++;
}
}
int main()
{
thread t1(increment);
thread t2(increment);
t1.join();
t2.join();
cout << counter.load() << endl;
return 0;
}
Результат выполнения кода:
200000
Смотрите также
-
метод
load,
который атомарно читает значение -
метод
store,
который атомарно записывает значение -
метод
fetch_add,
который атомарно прибавляет число -
метод
compare_exchange_strong,
который атомарно сравнивает и обменивает значение