我正在试验 C++0x 支持,但有一个问题,我想它不应该存在。要么我不明白主题,要么 gcc 有错误。
我有以下代码,最初 x
和 y
是相等的。线程 1 总是先递增 x
,然后递增 y
。都是原子整型值,所以自增完全没有问题。线程 2 正在检查 x
是否小于 y
,如果是则显示错误消息。
此代码有时会失败,但为什么呢?这里的问题可能是内存重新排序,但默认情况下所有原子操作都是顺序一致的,我没有明确放宽这些任何操作。我正在 x86 上编译这段代码,据我所知应该没有任何顺序问题。你能解释一下问题是什么吗?
#include <iostream>
#include <atomic>
#include <thread>
std::atomic_int x;
std::atomic_int y;
void f1()
{
while (true)
{
++x;
++y;
}
}
void f2()
{
while (true)
{
if (x < y)
{
std::cout << "error" << std::endl;
}
}
}
int main()
{
x = 0;
y = 0;
std::thread t1(f1);
std::thread t2(f2);
t1.join();
t2.join();
}
可以查看结果here .
最佳答案
比较有问题:
x < y
子表达式(在本例中为 x
和 y
)的求值顺序未指定,因此 y
可以在 x
或 x
可以在 y
之前求值。
如果先读取x
,你就有问题了:
x = 0; y = 0;
t2 reads x (value = 0);
t1 increments x; x = 1;
t1 increments y; y = 1;
t2 reads y (value = 1);
t2 compares x < y as 0 < 1; test succeeds!
如果您明确确保首先读取y
,则可以避免该问题:
int yval = y;
int xval = x;
if (xval < yval) { /* ... */ }
关于c++ - 内存排序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4012092/