# std::atomic_flag_test_and_set, std::atomic_flag_test_and_set_explicit

< cpp‎ | atomic

定义于头文件 `<atomic>` |  |
| (1) | (C++11 起)
bool atomic_flag_test_and_set( volatile std::atomic_flag* p ) noexcept; |  |
bool atomic_flag_test_and_set( std::atomic_flag* p ) noexcept; |  |
| (2) | (C++11 起)
bool atomic_flag_test_and_set_explicit( volatile std::atomic_flag* p, std::memory_order order ) noexcept; |  |
bool atomic_flag_test_and_set_explicit( std::atomic_flag* p, std::memory_order order ) noexcept; |  |

原子地更改 `p` 所指向的 std::atomic_flag 的状态为设置（ true ），并返回其先前所保有的值。

### 参数

p | - | 指向要访问的 std::atomic_flag 的指针
order | - | 此操作所用的内存同步顺序

### 返回值

`p` 所指向的标志先前保有的值

### 可能的实现

版本一
    bool atomic_flag_test_and_set(volatile std::atomic_flag* p)
    {
        return p->test_and_set();
    }
版本二
    bool atomic_flag_test_and_set(std::atomic_flag* p)
    {
        return p->test_and_set();
    }
版本三
    bool atomic_flag_test_and_set_explicit(volatile std::atomic_flag* p,
                                           std::memory_order order)
    {
        return p->test_and_set(order);
    }
版本四
    bool atomic_flag_test_and_set_explicit(std::atomic_flag* p,
                                           std::memory_order order)
    {
        return p->test_and_set(order);
    }

### 示例

能用 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 < 100; ++cnt) {
            while(std::atomic_flag_test_and_set_explicit(&lock, std::memory_order_acquire))
                 ; // 自旋直至获得锁
            std::cout << "Output from thread " << n << '\n';
            std::atomic_flag_clear_explicit(&lock, 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();
        }
    }

输出：

    Output from thread 2
    Output from thread 6
    Output from thread 7
    ...< 准确 1000 行 >...

### 参阅

atomic_flag (C++11) | 免锁的布尔原子类型 (类)
atomic_flag_clear atomic_flag_clear_explicit (C++11)(C++11) | 原子地设置标志值为 false (函数)
memory_order (C++11) | 为给定的原子操作定义内存顺序约束 (枚举)