I'm experimenting with C++0x support and there is a problem, that I guess shouldn't be there. Either I don't understand the subject or gcc has a bug.
I have the following code, initially x
and y
are equal. Thread 1 always increments x
first and then increments y
. Both are atomic integer values, so there is no problem with the increment at all. Thread 2 is checking whether the x
is less than y
and displays an error message if so.
This code fails sometimes, but why? The issue here is probably memory reordering, but all atomic operations are sequentially consistent by default and I didn't explicitly relax of those any operations. I'm compiling this code on x86, which as far as I know shouldn't have any ordering issues. Can you please explain what the problem is?
#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();
}
The result can be viewed here.
"error"
, (x
will always be greater than or equal toy
) is this what you wanted? – Chemise"error"
. But the code is if it is, print it.Thread 2 can see pairs of the form(n, n)
and(n + 1, n)
. In both cases,x < y
is false. There is one sequence that triggers it, though. @James: Yeah. – Adorable