为什么ATOMIC_FLAG_INIT为假?

时间:2013-07-26 14:14:05

标签: c++ c++11 atomic

C++11中,std::atomic_flag对线程循环很有用:

static std::atomic_flag s_done(ATOMIC_FLAG_INIT);

void ThreadMain() {
    while (s_done.test_and_set()) {  // returns current value of s_done and sets to true
        // do some stuff in a thread
    }
}

// Later:
  s_done.clear();  // Sets s_done to false so the thread loop will drop out

ATOMIC_FLAG_INIT将标志设置为false,这意味着线程永远不会进入循环。 (坏)解决方案可能会这样做:

void ThreadMain() {
    // Sets the flag to true but erases a possible false
    // which is bad as we may get into a deadlock
    s_done.test_and_set();
    while (s_done.test_and_set()) {
        // do some stuff in a thread
    }
}

std::atomic_flag的默认构造函数指定该标志将处于未指定状态。

我可以将atomic_flag初始化为true吗?这是atomic_flag的正确用法吗?

3 个答案:

答案 0 :(得分:4)

在启动主题之前,您始终可以调用test_and_set

答案 1 :(得分:2)

您错误地使用atomic_flag来实现自旋锁。正确的形式是:

static std::atomic_flag s_done(ATOMIC_FLAG_INIT);

void ThreadMain() {
    while (s_done.test_and_set()) {  // returns current value of s_done and sets to true
        // spin while s_done is held by another thread
    }

    // do some stuff in a thread

    // Later:
    s_done.clear();  // Sets s_done to false so the thread loop will drop out

虽然我建议使用RAII支架,但您可以returnthrow功能正常,锁定将自动释放。

ATOMIC_FLAG_INITfalse,因为atomic_flag的值通常被解释为指示某个资源是否由线程独占。在程序启动时,没有这样的线程,实际上相关的资源甚至可能没有被初始化。因此false将是适当的初始值。

至于初始化为true,标准不保证甚至可以为atomic_flag分配布尔值。

答案 2 :(得分:2)

未使用ATOMIC_FLAG_INIT(或{0})初始化的原子标志处于不确定状态。

你可以做些什么来解决你的问题:

std::atomic_flag lock = ATOMIC_FLAG_INIT;

现在获得锁定:

while (lock.test_and_set(std::memory_order_acquire))
    ; // ...

然后释放它:

lock.clear(std::memory_order_release); 

这就是所谓的spin-lock