vector iterator not deferencable
-
ich habe hier ein ganz komisches problem:
ich erstelle in einer meiner methoden einen thread der eine andere methode aufruft.
class test { public: void methode1(); void methode2(); private: meineStruct me; vector<std::thread> t; vector<meineStruct> s; };void Test::methode1() { me.WasAuchImmer = "Foo"; t.push_back(&Test::methode2, this); s.push_back(me); } void Test::methode2() { std::cout << s.front().WasAuchImmer << std::endl; }wenn ich in meinem programm nun methode1() aufrufe bekomme ich folgende fehlermeldung: vector iterator not deferencable
wenn ich jedoch in methode2() ein cout davorsetze:void Test::methode2() { std::cout << s.size() << std::endl; std::cout << s.front().WasAuchImmer << std::endl; }... funktioniert es einwandfrei. Wieso?
-
Achja,
t.push_back(&Test::methode2, this);muss natürlich so heißen:
t.push_back(std::thread(&test::methode2, this));
-
Race condition. Wenn die Methode2 ausgeführt wird, hat s bei s.front() wohl noch keine Elemente, da das s.push_back(me); noch nicht erfolgt ist. Durch das cout verzögert sich der Zugriff genug, dass im Hauptthread mittlerweile ein Element zu s hinzu gefügt wurde. Oder umgekehrt wird durch das push_back vielleicht der front-Iterator ungültig, zwischen dem Zeitpunkt wo er geholt wird und dem Zeitpunkt, an dem er dereferenziert wird. Kommt auf den Gesamtkontext an.
Allgemein: Die STL-Container sind in der Regel nicht threadsicher. Wenn ein Thread schreibend zugreift, ganz besonders wenn er wie hier Iteratoren ungültig machen kann, dann musst du das absichern.
-
klingt logisch, was gibt es denn für möglichkeiten sowas abzusichern?
-
HELP__ schrieb:
klingt logisch, was gibt es denn für möglichkeiten sowas abzusichern?
Wenn du mit Threads arbeitest, dann empfehle ich ganz dringend, dazu ein Tutorial zu lesen. Selbst wenn ich dir jetzt was von std::mutex erzähle: Learning by doing funktioniert hier nur schlecht. Du musst schon einen Plan haben und die Mittel der Sprache kennen (eine Referenz reicht da nicht), sonst läufst du direkt in das nächste Problem. Denn mögliche Probleme gibt es bei der nebenläufigen Programmierung sehr viele, du hast gerade einen der einfachsten Problemfälle gefunden.
Du musst auch ein gutes Gefühl über den Aufbau von Datenstrukturen haben, damit du weißt, was erlaubt ist und was nicht. Es ist beispielsweise kein Problem, gleichzeitig auf verschiedene Elemente eines vectors zuzugreifen, da wäre eine Absicherung bloß unnötiger Overhead.
-
ich habe jetzt zum beispiel das hier gefunden: http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-4-protecting-shared-data.html - taugt das was?
und noch eine letzte kleine zwischenfrage:
mit zugreifen meinst du lesend zugreifen? weil wenn ich zum beispiel in einem thread die größe des vectors halbiere und gleichzeitig in einem anderen thread auf einen teil des gerade gelöschten vectors zugreife kann das ja nur schiefgehen.
-
HELP__ schrieb:
mit zugreifen meinst du lesend zugreifen?
Allgemein darfst du nicht gleichzeitig etwas ändern, worauf ein anderer Thread gerade zugreift, egal ob Lesend oder Schreibend. Der Trick ist zu wissen, welche Operationen an einer Datenstruktur welche Arten von Änderungen zur Folge haben können.
ich habe jetzt zum beispiel das hier gefunden: http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-4-protecting-shared-data.html - taugt das was?
Sieht auf den ersten Blick brauchbar aus, ist aber unvollständig. Letzter Beitrag von 2012 wo ein nächster Teil angekündigt wird. Das verheißt nichts gutes.
Eventuell wäre es besser, erst einmal allgemein etwas zu Threads zu lernen und sich dann anzusehen, wie das in C++ gemacht wird. Das Online-Material zu C++11-Threads ist meiner Erfahrung nach noch ziemlich dünn. Vielleicht wäre ein Buch etwas für dich:
http://www.c-plusplus.net/forum/302555
Mindestens in dem zweiten gibt es gleich mehrere Kapitel über die C++11-Threads (in dem anderen Buch aber bestimmt auch, ich kenne es bloß nicht). Setzt aber ein bisschen voraus, dass man schon ungefähr weiß, was man da tut.
-
Hier ist ein gutes Buch für Dich:
"C++ Concurrency in Action"
-
habe mir jetzt mal "C++11 programmieren" und "C++ Concurrency in Action" bestellt, danke für die tipps
