Cygwin GCC kullanıyorum ve şu kodu çalıştırıyorum:
#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;
}
Çizgi ile Derleyen: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.
Doğru olan 1000 yazdırır. Ancak, daha önce artırılmış bir değerin üzerine yazılan iş parçacıkları nedeniyle daha az bir sayı bekliyordum. Bu kod neden karşılıklı erişimden zarar görmüyor?
Test makinemde 4 çekirdek var ve bildiğim programa herhangi bir kısıtlama koymuyorum.
Paylaşılan içeriğin foo
daha karmaşık bir şeyle değiştirilmesi durumunda sorun devam eder , örneğin
if (u % 3 == 0) {
u += 4;
} else {
u -= 1;
}
while true; do res=$(./a.out); if [[ $res != 1000 ]]; then echo $res; break; fi; done;
sistemimde 999 veya 998 yazdırması gibi bir şey .
u
belleğe geri yazacak . CPU, bellek satırınınu
CPU'nun önbelleğinde olmadığını fark etmek gibi şaşırtıcı şeyler yapacak ve artırma işlemini yeniden başlatacaktır. Bu nedenle x86'dan diğer mimarilere geçmek, göz açıcı bir deneyim olabilir!