Warum Programm mit diesem Code manchmal "2" druckt?C++ atomare Lese-/Schreib-Missverständnis
int main() {
std::atomic<int> a;
a = 0;
std::thread t1([&]{++a;});
std::thread t2([&]{a++;});
std::thread t3([&]{
a = a.load() + 1;
});
t1.join();
t2.join();
t3.join();
if (a != 3) {
std::cout << "a: " << a << std::endl;
}
}
Ich habe gedacht std::atomic
garantiert, dass alle Operationen atomar erfolgen wird also hier das Schreiben (Erhöhen) eine Speicherbarriere verwenden und wir werden immer 3
am Ende des Threads arbeiten. Ich habe den Code erforscht und herausgefunden, dass der Problemthread t3
ist, aber ich kann nicht verstehen, warum es falsch ist.
'a = a.load() + 1 'ist nicht nur eine Operation. –
++ a und a ++ wird nicht atomar durchgeführt. Vielleicht möchten Sie einen Blick auf http://en.cppreference.com/w/cpp/atomic/atomic/fetch_add werfen – Rush
@Rush Was ist damit dann? http://en.cppreference.com/w/cpp/atomic/atomic/operator_arith @ JonathanPotter Ich habe so gedacht, aber wie funktioniert dann inkrementieren? Ich denke, es braucht zumindest einen zu lesen, oder? Also habe ich in 't3' versucht, es zu simulieren, aber es scheint, dass es falsch ist, wie @ ParkYoung-Bae sagte. Also ich denke das Problem ist, dass 't3' mit einem alten Wert überschreibt. –