Estou usando Cygwin GCC e executo 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 com a linha: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.
Ele imprime 1000, o que é correto. No entanto, eu esperava um número menor devido a threads substituindo um valor incrementado anteriormente. Por que este código não sofre de acesso mútuo?
Minha máquina de teste tem 4 núcleos e não coloquei restrições no programa que conheço.
O problema persiste ao substituir o conteúdo do compartilhado foo
por algo mais complexo, por exemplo
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 ou 998 em meu sistema.
u
volta na memória. A CPU realmente fará coisas incríveis como notar que a linha de memóriau
não está no cache da CPU e reiniciará a operação de incremento. É por isso que ir de x86 para outras arquiteturas pode ser uma experiência reveladora!