std::atomic_flag
Определено в заголовочном файле <atomic> | ||
|---|---|---|
class atomic_flag; | (с C++11) |
std::atomic_flag — это атомный булевый тип. В отличие от всех специализаций std::atomic, гарантируется отсутствие блокировок. В отличие от std::atomic<bool>, std::atomic_flag не предоставляет операций загрузки или сохранения.
Члены
| создаёт atomic_flag (публичный член-функция) |
|
|
[удалено] | оператор присваивания (удален) (публичный член-функция) |
атомарно устанавливает флаг в false (публичный член-функция) |
|
атомарно устанавливает флаг в true и получает его предыдущее значение (публичный член-функция) |
|
|
(C++20) | атомарно возвращает значение флага (публичный член-функция) |
|
(C++20) | блокирует поток до получения уведомления и изменения атомного значения (публичный член-функция) |
|
(C++20) | уведомляет, по крайней мере, один ожидающий поток об атомном объекте (публичный член-функция) |
|
(C++20) | уведомляет все заблокированные потоки, ожидающие атомного объекта (публичный член-функция) |
Пример
Демонстрация мьютекса спин-блокировки может быть реализована в пользовательском пространстве с помощью atomic_flag. Обратите внимание, что мьютексы спин-блокировки на практике очень сомнительны.
#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
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)) // acquire lock
{
// Since C++20, it is possible to update atomic_flag's
// value only when there is a chance to acquire the lock.
// See also: https://stackoverflow.com/questions/62318642
#if defined(__cpp_lib_atomic_flag_test)
while (lock.test(std::memory_order_relaxed)) // test lock
#endif
; // spin
}
static int out{};
std::cout << n << ((++out % 40) == 0 ? '\n' : ' ');
lock.clear(std::memory_order_release); // release lock
}
}
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
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 3756 | C++23 | неясно, безопасен ли он для сигналов | он безопасен для сигналов |
См. также
|
(C++11)(C++11) | атомарно устанавливает флаг в 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 |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/atomic/atomic_flag