注意!
我显然没有向这里的每个人清楚地表达我的观点,这令人非常沮丧。我的目标是打消
volatile
实际上是无操作的神话,它什么都不做。我并没有试图说它应该被使用,它是必不可少的,它不是多余的等等。我已经证明
volatile
仍然做了一件事。我承认在某些情况下它是多余的,并且多线程示例是一个糟糕的选择。我也没有试图隐瞒我的答案的初始修订包含错误这一事实。但是这个Q& A甚至没有达到其预期目的。为此,我认为是时候把它扔掉了。
感谢Kerrek和T.C.为了他们的见解。我只是不认为他们的回答符合我想问的问题。我很确定这是我的错误。
因此我放弃它!并将其作为问题的副本而不是它的意图,但它被解释为。
干杯! (& hth。)
我正在写一个线程中的变量并在另一个线程中读取它。我被告知,volatile
对此完全无用,除非我正在使用硬件,否则我不需要在这个时代使用它。
int x = 0;
void thread1()
{
while (true) {
sleep(1);
if (x > 0)
break;
}
}
void thread2()
{
while (true) {
sleep(1);
x++;
}
}
在这种情况下,使用volatile
可以获得任何收益吗?
如果x
不是简单的int
而是类类型呢?
答案 0 :(得分:20)
您被正确告知,volatile
对于线程间通信没有用。不要为此目的使用它。它不提供同步,并为您的代码留下数据争用。相反,在正确同步对共享状态的访问时,您不需要volatile
。
“你是什么意思”的正确代码使用原子变量进行共享状态或使用互斥锁保护共享状态,并且所有线程都会正确地观察共享状态。例如:
#include <atomic>
std::atomic<int> x = 0;
void thread1()
{
while (true) {
sleep(1);
if (x > 0)
break;
}
}
void thread2()
{
while (true) {
sleep(1);
x++;
}
}
任何时候都不需要volatile
。
请注意,volatile
在线程中可能很有用,可以强制执行一个没有副作用的循环:
// Spend some time
for (volatile int i = 0; i != LARGE_NUMBER; ++i)
{ /* do nothing */ }
// or even:
for (int i = 0; const_cast<volatile int &>(i) != LARGE_NUMBER; ++i) {}