Sto usando Cygwin GCC ed eseguo questo codice:
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
unsigned u = 0;
void foo()
{
u++;
}
int main()
{
vector<thread> threads;
for(int i = 0; i < 1000; i++) {
threads.push_back (thread (foo));
}
for (auto& t : threads) t.join();
cout << u << endl;
return 0;
}
Compilato con la linea: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.
Stampa 1000, che è corretto. Tuttavia, mi aspettavo un numero inferiore a causa dei thread che sovrascrivono un valore precedentemente incrementato. Perché questo codice non soffre di accesso reciproco?
La mia macchina di prova ha 4 core e non metto restrizioni al programma che conosco.
Il problema persiste quando si sostituisce il contenuto del condiviso foo
con qualcosa di più complesso, es
if (u % 3 == 0) {
u += 4;
} else {
u -= 1;
}
while true; do res=$(./a.out); if [[ $res != 1000 ]]; then echo $res; break; fi; done;
stampa 999 o 998 sul mio sistema.
u
in memoria. La CPU in realtà farà cose sorprendenti come notare che la linea di memoria peru
non è nella cache della CPU e riavvierà l'operazione di incremento. Questo è il motivo per cui passare da x86 ad altre architetture può essere un'esperienza che apre gli occhi!