Пространства имён
Варианты
Действия

std::atomic_flag

Материал из cppreference.com
< cpp‎ | atomic
 
 
Библиотека атомарных операций
 
 
Определено в заголовочном файле <atomic>
class atomic_flag;
(начиная с C++11)

std::atomic_flag атомарный логический тип. В отличие от всех специализаций std::atomic, он гарантированно свободен от блокировок. В отличие от std::atomic<bool>, std::atomic_flag не предоставляет операций load или store.

[править] Функции-элементы

создаёт atomic_flag
(public функция-элемент)
оператор присваивания
(public функция-элемент)
атомарно устанавливает флаг в false
(public функция-элемент) [править]
атомарно устанавливает флаг в true и получает его предыдущее значение
(public функция-элемент) [править]
(C++20)
атомарно возвращает значение флага
(public функция-элемент) [править]
блокирует поток до тех пор, пока не получит уведомление и не изменится атомарное значение
(public функция-элемент) [править]
уведомляет хотя бы один поток, ожидающий атомарный объект
(public функция-элемент) [править]
уведомляет все потоки, заблокированные в ожидании атомарного объекта
(public функция-элемент) [править]

[править] Пример

Демонстрация мьютекса спин-блокировки может быть реализована в пользовательском пространстве с помощью atomic_flag. Обратите внимание, что мьютексы спин-блокировки крайне сомнительны на практике.

#include <thread>
#include <vector>
#include <iostream>
#include <atomic>
 
std::atomic_flag lock = ATOMIC_FLAG_INIT;
 
void f(int n)
{
    for (int cnt = 0; cnt < 40; ++cnt) {
        while (lock.test_and_set(std::memory_order_acquire)) {  // запрос блокировки
        // Начиная с C++20, можно обновить значение atomic_flag
        // только тогда, когда есть возможность получить блокировку.
        // Смотрите также: https://stackoverflow.com/questions/62318642
        #if defined(__cpp_lib_atomic_flag_test)
            while (lock.test(std::memory_order_relaxed))        // тестирование блокировки
        #endif
                ; // spin
        }
        static int out{};
        std::cout << n << ((++out % 40) == 0 ? '\n' : ' ');
        lock.clear(std::memory_order_release);                  // освобождение блокировки
    }
}
 
int main()
{
    std::vector<std::thread> v;
    for (int n = 0; n < 10; ++n) {
        v.emplace_back(f, n);
    }
    for (auto& t : v) {
        t.join();
    }
}

Возможный вывод:

0 1 1 2 0 1 3 2 3 2 0 1 2 3 2 3 0 1 3 2 0 1 2 3 2 3 0 3 2 3 2 3 2 3 1 2 3 0 1 3
2 3 2 0 1 2 3 0 1 2 3 2 0 1 2 3 0 1 2 3 2 3 2 3 2 0 1 2 3 2 3 0 1 3 2 3 0 2 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 3 2 0 2 3 2 3 2 3 2 3 2 3 0 3
2 3 0 3 0 3 2 3 0 3 2 3 2 3 0 2 3 0 3 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9

[править] Смотрите также

атомарно устанавливает флаг в true и возвращает его предыдущее значение
(функция) [править]
атомарно устанавливает значение флага в false
(функция) [править]
блокирует поток до тех пор, пока не получит уведомление и не изменится флаг
(функция) [править]
уведомляет поток, заблокированный в atomic_flag_wait
(функция) [править]
уведомляет все потоки, заблокированные в atomic_flag_wait
(функция) [править]
инициализирует std::atomic_flag значением false
(макроконстанта) [править]