I wrote the following piece of code:
#include <thread>
#include <iostream>
void thread(bool &t1, bool &t2, int &nn) {
t1 = true;
if (!t2) {
nn--;
}
}
int main(int argc, char *argv[]) {
bool t1, t2;
int nn;
for (std::size_t i = 0; true; ++i) {
t1 = false;
t2 = false;
nn = 1;
std::thread runner1(thread, std::ref(t1), std::ref(t2), std::ref(nn));
std::thread runner2(thread, std::ref(t2), std::ref(t1), std::ref(nn));
runner1.join();
runner2.join();
if (nn < 0) {
std::cout << "ERROR! " << nn << ". Took " << i << " trials." << std::endl;
return nn;
}
}
}
Notice that thread1 writes t1
to true
and t2
checks if t2
is false
to decrease nn
, while thread2 does the inverted check. There should be a scheduling of these two threads in which both of them end up decreasing nn
, and thus nn
becomes -1.
A very similar example in Java does indeed end up exiting with an error within 10 seconds, however, this example I have left running for more than 10 minutes without any exits.
I have compiled with debug information (no optimizations, under MingW), and checked that the compiler does not optimize the thread
function. I thought that it may be a problem I did not understand with using std::ref, but changing the references for pointers did not fix it either.
Why is it that this program does not fail? Do I have the wrong idea about the C++ memory model? Is there a stronger condition that Windows' threading implementation maintains?.
Aucun commentaire:
Enregistrer un commentaire