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
”的唯一方法是所有位都不为零的值的别名。我没有试图实现自旋锁,我在循环中等待一个条件变量。这只是表示线程应该退出。