Ich habe einen Code in Arbeit, der mehrere Threads startet, die einige Operationen ausführen, und wenn einer von ihnen fehlschlägt, setzen sie die freigegebene Variable auf false.Gibt es eine implizite Speicherbarriere mit synchronisierten Beziehungen auf Thread :: Join?
Dann verbindet Hauptthread alle Worker-Threads. Simulation sieht das ungefähr so (ich aus der möglichen Lösung kommentiert, die ich weiß nicht, ob es gebraucht wird):
#include <thread>
#include <atomic>
#include <vector>
#include <iostream>
#include <cassert>
using namespace std;
//atomic_bool success = true;
bool success = true;
int main()
{
vector<thread> v;
for (int i = 0; i < 10; ++i)
{
v.emplace_back([=]
{
if (i == 5 || i == 6)
{
//success.store(false, memory_order_release);
success = false;
}
});
}
for (auto& t : v)
t.join();
//assert(success.load(memory_order_acquire) == false);
assert(success == false);
cout << "Finished" << endl;
cin.get();
return 0;
}
Gibt es eine Möglichkeit, dass Hauptthread obwohl die Erfolgsvariable als wahr sogar lesen einer der Arbeiter setzte es auf false?
Ich fand, dass Thread :: join() ist eine vollständige Speichersperre (source), aber das mit dem von Erfolg Variable aus dem Haupt-Thread lesen folgenden synchronisierten mit Beziehung bedeutet, so dass wir hast du garantiert den neuesten Wert?
Ist die Korrektur, die ich (in dem kommentierten Code) gepostet habe, notwendig in diesem Fall (oder vielleicht eine andere Korrektur, wenn diese falsch ist)?
Gibt es eine Möglichkeit, dass der Erfolg Variable gelesen wird entfernt werden optimiert (da es nicht flüchtig ist), und wir werden alte Wert erhalten, unabhängig von suppossed implizite Gedächtnis Barriere auf Thread existieren :: beitreten?
Der Code ist für die Arbeit mit mehreren Architekturen (ich kann mich nicht an alle erinnern, ich habe kein Makefile vor mir), aber es gibt atleast x86, amd64, itanium, arm7.
Danke für jede Hilfe mit diesem.
Edit: Ich habe das Beispiel geändert, weil in der realen Situation mehr als ein Thread versuchen kann, Erfolg Variable schreiben.
Ist die Quelle nicht klar darüber? "Da die Erstellung und Struktur von Threads als eine Synchronisierungsoperation definiert ist, wird ein Thread nach dem Ende dieses Threads notwendigerweise verbunden. So sehen Sie alles, was unbedingt geschehen muss, bevor der Thread beendet wurde." –
Ich bin mir nicht sicher seit, wie Sie hier http: //en.cppreference sehen können.com/w/cpp/atomic/atomic_thread_fence Verweis erwähnt nur die Synchronisation zwischen Zäunen und atomaren Objekten, gibt es nichts über die Synchronisation zwischen Zäunen und gewöhnlichen Objekten. Ich denke, beitreten verwendet solche Zaun intern, aber ich kann falsch liegen. – Mikaka
[Ja] (https://timsong-cpp.github.io/cppwp/thread.thread.member#4). Sonst wäre "Join" eher nutzlos. –