C++ 为什么原子标志是假的?

C++ 为什么原子标志是假的?,c++,c++11,atomic,C++,C++11,Atomic,在C++11中有std::atomic_标志,它对线程循环很有用: 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:

C++11
中有
std::atomic_标志
,它对线程循环很有用:

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
的默认构造函数指定该标志将处于未指定状态


我是否可以将
原子_标志
初始化为
?这是否正确使用了
原子\u标志

在启动线程之前,您始终可以调用
测试和设置

您错误地使用了
原子\u标志
来实现自旋锁。正确的形式是:

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支架,这样您可以
返回
抛出
中间功能,锁将自动释放

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


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

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

要解决您的问题,您所能做的是:

std::atomic_flag lock = ATOMIC_FLAG_INIT;
现在获取锁:

while (lock.test_and_set(std::memory_order_acquire))
    ; // ...
然后将其释放:

lock.clear(std::memory_order_release); 

这就是所谓的
旋转锁

我在我的代码中已经做过了,但它感觉很奇怪,让你抓狂。我只是想知道为什么不能在初始化时将
atomic_标志设置为
true
?因为它是用来构建其他原语的低级原语,而不是用于一般用途
atomic
是钱的所在。好吧,我现在知道
atomic_标志
更多地用于自旋锁,而不是用于向线程发送信号以从其循环中转储,我猜这就是你所说的
std::atomic\u bool
的用途@R.MartinhoFernandes。你可能已经知道了,但是可以将
atomic
初始化为
true
false
@Matt atomic\u FLAG\u INIT没有将标志设置为
false
,而是将其初始化为零,这是具有静态或线程本地存储持续时间的对象的默认值。@Stefan“将其初始化为零”与“将标志设置为
false
”相同,否?@Matt这是错误的措辞,尽管0==false且语义相同,但它不正确。您希望将一个对象初始化为零而不是false。@Stefan那么您将如何调用
static bool s_bool=false?是“初始化为
false
”、“设置为
false
”还是“初始化为
0
”?如果你有一个系统,当
false
时,我能看到“设置为
false
”和“初始化为
zero
”的唯一方法是所有位都不为零的值的别名。我没有试图实现自旋锁,我在循环中等待一个
条件变量。这只是表示线程应该退出。