std::atomic_flag
Материал из cppreference.com
Определено в заголовочном файле <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 и возвращает его предыдущее значение (функция) | |
(C++11)(C++11) |
атомарно устанавливает значение флага в false (функция) |
(C++20)(C++20) |
блокирует поток до тех пор, пока не получит уведомление и не изменится флаг (функция) |
(C++20) |
уведомляет поток, заблокированный в atomic_flag_wait (функция) |
(C++20) |
уведомляет все потоки, заблокированные в atomic_flag_wait (функция) |
(C++11) |
инициализирует std::atomic_flag значением false (макроконстанта) |
Документация C по atomic_flag
|