Estoy usando Cygwin GCC y ejecuto este código:
#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;
}
Compilado con la línea: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.
Imprime 1000, que es correcto. Sin embargo, esperaba un número menor debido a que los subprocesos sobrescribían un valor incrementado previamente. ¿Por qué este código no sufre de acceso mutuo?
Mi máquina de prueba tiene 4 núcleos y no pongo restricciones al programa que conozco.
El problema persiste al reemplazar el contenido del compartido foo
por algo más complejo, p. Ej.
if (u % 3 == 0) {
u += 4;
} else {
u -= 1;
}
while true; do res=$(./a.out); if [[ $res != 1000 ]]; then echo $res; break; fi; done;
imprime 999 o 998 en mi sistema.
u
volver a escribir en la memoria. La CPU realmente hará cosas asombrosas como notar que la línea de memoria parau
no está en el caché de la CPU y reiniciará la operación de incremento. ¡Es por eso que pasar de x86 a otras arquitecturas puede ser una experiencia reveladora!