2

其中C++11std::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_flagtotrue吗?这是正确的用法atomic_flag吗?

4

3 回答 3

5

您总是可以test_and_set在启动线程之前调用。

于 2013-07-26T14:17:42.933 回答
4

您错误地使用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因为 an 的值atomic_flag通常被解释为指示某个资源是否由线程独占。在程序启动时,没有这样的线程,实际上相关的资源甚至可能还没有被初始化。false适当的初始值也是如此。

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

于 2013-07-26T14:33:00.553 回答
2

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

你可以做的是解决你的问题是这样的:

std::atomic_flag lock = ATOMIC_FLAG_INIT;

现在获取锁:

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

然后释放它:

lock.clear(std::memory_order_release); 

这就是所谓的spin-lock

于 2013-07-26T14:34:15.707 回答