Я використовую Cygwin GCC і запускаю цей код:
#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;
}
Зібраний з лінії: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.
Він друкує 1000, що правильно. Однак я очікував меншої кількості через тему, що перезаписала раніше збільшене значення. Чому цей код не страждає від взаємного доступу?
Мій тестовий апарат має 4 ядра, і я не ставлю обмежень на програму, про яку я знаю.
Проблема зберігається під час заміни вмісту спільного доступу foo
чимось складнішим, наприклад
if (u % 3 == 0) {
u += 4;
} else {
u -= 1;
}
while true; do res=$(./a.out); if [[ $res != 1000 ]]; then echo $res; break; fi; done;
друкує 999 або 998 на моїй системі.
u
назад до пам'яті. Процесор насправді буде робити дивовижні речі, як-от зауважити, що лінія пам'яті для пам'ятіu
відсутня в кеші процесора, і вона перезапустить операцію збільшення. Ось чому перехід від x86 до інших архітектур може стати досвідом відкриття!