ฉันใช้ 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
รวบรวมกับเส้น:
มันพิมพ์ 1,000 ซึ่งถูกต้อง อย่างไรก็ตามฉันคาดว่าจะมีจำนวนน้อยกว่าเนื่องจากเธรดเขียนทับค่าที่เพิ่มขึ้นก่อนหน้านี้ เหตุใดรหัสนี้จึงไม่ได้รับผลกระทบจากการเข้าถึงซึ่งกันและกัน
เครื่องทดสอบของฉันมี 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
กลับไปที่หน่วยความจำ CPU จะทำสิ่งที่น่าอัศจรรย์เช่นสังเกตว่าสายหน่วยความจำสำหรับu
ไม่ได้อยู่ในแคชของ CPU และจะเริ่มการทำงานที่เพิ่มขึ้นใหม่ นี่คือเหตุผลว่าทำไมการเปลี่ยนจาก x86 ไปยังสถาปัตยกรรมอื่น ๆ อาจเป็นประสบการณ์เปิดหูเปิดตา!