Namespaces
Variants

std:: atomic_flag

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
atomic_flag
(C++11)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Definiert im Header <atomic>
class atomic_flag ;
(seit C++11)

std::atomic_flag ist ein atomarer boolescher Typ. Im Gegensatz zu allen Spezialisierungen von std::atomic ist garantiert lock-free. Im Gegensatz zu std:: atomic < bool > bietet std::atomic_flag keine Lade- oder Speicheroperationen.

Memberfunktionen

Konstruiert einen atomic_flag
(öffentliche Elementfunktion)
[deleted]
Der Zuweisungsoperator (gelöscht)
(öffentliche Elementfunktion)
Setzt das Flag atomar auf false
(öffentliche Elementfunktion)
Setzt das Flag atomar auf true und ermittelt seinen vorherigen Wert
(öffentliche Elementfunktion)
(C++20)
Gibt den Wert des Flags atomar zurück
(öffentliche Elementfunktion)
(C++20)
Blockiert den Thread, bis benachrichtigt und der atomare Wert sich ändert
(öffentliche Elementfunktion)
(C++20)
Benachrichtigt mindestens einen auf das atomare Objekt wartenden Thread
(öffentliche Elementfunktion)
(C++20)
Benachrichtigt alle auf das atomare Objekt blockiert wartenden Threads
(öffentliche Elementfunktion)

Beispiel

Eine Spinlock -Mutex-Demo kann im Userspace mit einem atomic_flag implementiert werden. Beachten Sie, dass Spinlock-Mutexes in der Praxis äußerst fragwürdig sind.

#include <atomic>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
class mutex
{
    std::atomic_flag m_{};
  public:
    void lock() noexcept
    {
        while (m_.test_and_set(std::memory_order_acquire))
#if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
            // Since C++20, locks can be acquired only after notification in the unlock,
            // avoiding any unnecessary spinning.
            // Note that even though wait guarantees it returns only after the value has
            // changed, the lock is acquired after the next condition check.
            m_.wait(true, std::memory_order_relaxed)
#endif
                ;
    }
    bool try_lock() noexcept
    {
        return !m_.test_and_set(std::memory_order_acquire);
    }
    void unlock() noexcept
    {
        m_.clear(std::memory_order_release);
#if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L
        m_.notify_one();
#endif
    }
};
static mutex m;
static int out{};
void f(std::size_t n)
{
    for (std::size_t cnt{}; cnt < 40; ++cnt)
    {
        std::lock_guard lock{m};
        std::cout << n << ((++out % 40) == 0 ? '\n' : ' ');
    }
}
int main()
{
    std::vector<std::thread> v;
    for (std::size_t n{}; n < 10; ++n)
        v.emplace_back(f, n);
    for (auto &t : v)
        t.join();
}

Mögliche Ausgabe:

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

Siehe auch

setzt das Flag atomar auf true und gibt seinen vorherigen Wert zurück
(Funktion)
setzt den Wert des Flags atomar auf false
(Funktion)
blockiert den Thread, bis eine Benachrichtigung erfolgt und das Flag sich ändert
(Funktion)
benachrichtigt einen in atomic_flag_wait blockierten Thread
(Funktion)
benachrichtigt alle in atomic_flag_wait blockierten Threads
(Funktion)
initialisiert ein std::atomic_flag auf false
(Makrokonstante)
C-Dokumentation für atomic_flag