Threads kommen sich in die Quere
-
Hallo!
Ich habe vor mir eine Verkette Liste zu Programmieren (Klasse). Soweit so gut. Das ist ja auch einfach. Aber ich möchte jetzt von 2 threads in die liste schreiben bzw. etwas rauslöschen. Ich hab bis jetzt noch keinen Source aber so wie ich mir das jetzt schon gedacht hab können sich die threads ja im schlimmsten fall (bei schei* timing ^^) in die quere kommen. sodass der eine ein listenelement löscht von dem der andere grad liest. usw... da gibts noch einige solche sachen. Wie kann man sowas abfangen. Es soll also nur jeweils in thread mit der liste arbetien dürfen, der andere soll solange warten.
Mir gehts jetzt nicht um nen fertigen source, einfach nur so die grundidee oder auch pseudocode oder irgendnen tip eben.Danke im voraus,
DerVormPC
-
wenn du mit nebenlaeufiger Programmierung vertraut bist, dann sollte dir der "Mutex" ein Begriff sein: http://de.wikipedia.org/wiki/Mutex
Du sicherst Zugriffe auf deine Liste einfach mit einem Mutex ab.ansonsten wuerd ich dir raten, std::list statt eigener List-Klassen zu verwenden
-
std::list ist aber nicht threadsafe, mutexen musste also trotzdem noch.
-
Die ganze STL ist nicht threadsicher. Logisch, da es ja keine Threads im Standard gibt.
-
std::list ist aber nicht threadsafe
Die ganze STL ist nicht threadsicher.
glaub hier liegt nen sprachlisches Missverstaendniss vor.
Die meisten STL impls sind sehr wohl "threadsafe", aber die bedeutung scheint ned so klar zu sein.
threadsafe = das der user ueberhaupt in der Lage ist, seine anwendung multithreaded zu machen. Das heisst er muss sehr wohl mit Synchronisationsobjecten seine daten selbst sichern, das nimmt ihm auch wohl keine Biblo ab (die waeren zumindest maechtig unperformant, weil nur der programmierer selbst kann den optimalen schutz bestimmen).
threadsicher bedeutet einfach nur, das die Objekte sich intern nich ins gehege kommen, wo der anwendungsprogrammierer keine chance hat, den zugriff zu abzusichern. Beispielsweise dass sie eben keine globalen ungesicherten objecte verwenden.
Es gibt auch einige beispile von nichtthreadsicheren Biblios.
Zum Beispiel ein Teil der QT. Es hat schon einen Grund warum man nur einen Ansichts-Thread da haben kann .... also auf GUI Objecte nicht mit mehreren Threads zugegriffen werden kann. da kann man schutzen mit mutexen wie man will, man hat keine chance, wenn QObject irgendwo global was schmutziges macht ...Ciao ...
-
Ok Danke!
Ich hab mir da bissl was durchgelesen jetzt und ich glaub ich raffs. ^^
Abr ich glaub cih mach das lieber mit EnterCriticalSection() usw.is viel einfacher.
Hab ich auf CodeProhejct gelesen. ^^
-
"Mutex" iss eigentlich nur nen Fachbegriff fuer etwas, was etwas bestimmtes tut
Allgemein iss Mutex eine sperre, die immer nur einen thread passieren laesst, und den anderen solange blockiert, bis der andere Thread wieder die sperre aufhebt.Wie man das realisiert iss volkommen wurscht:
Man kann das selber bauen, in dem man garantiert atomare schreiboperationen verwendet und nen geeignteten datentyp damit manipuliert, oder man verwendet BS funktionen die genau dafuer zustaendig sind ... oder man verwendet "Events" die ebenfalls dafuer geeignet sind ...::EnterCriticalSection, ::CreateCriticalSection ... sind genau die Win32 spezifischen c-Funktionen dafuer. also hasst du grad nen plain C-Mutex benutzt.
Unter C++ solltest trotzdem abstrahieren, und die c-Funktionen nich Blank verwenden. Ob nun selbst ne Klasse drum wrappst oder CCriticalSection(MFC) oder CComCriticalSection (ATL) oder sonst was fuer ne Bib verwendest iss eigentlich egal ...
wichtig ist nur, das man besonders bei methoden mit exception handling oder mehreren aussprungpfaden folgendes Konstrukt wahnsinnig Nutzlich ist ...template<class Mutex_T> class ObjectLock { public: ObjectLock(Mutex_T & rxLockObj):mrxLockObj(rxLockObj){ mrxLockObj.Lock(); } ~ObjectLock(){ mrxLockObj.Unlock(); } private: Mutex_T & mrxLockObj };
Wie das teil nun funzt, und warum das so wahnsinnig nuetzlich iss, darauf solltest selber kommen ....
Ciao ...
-
...Listenimplementierungen, die komplett ohne Synchronisation arbeiten können. Voraussetzung: Nur ein Thread schreibt, ein anderer liest. Vorteil: Speed, da keiner warten muß. Nachteil: Wenn mehrere Threads lesen, muß das Lese-Interface leider doch mit einem Lock versehen werden.
-
Es gibt auch... schrieb:
...Listenimplementierungen, die komplett ohne Synchronisation arbeiten können. Voraussetzung: Nur ein Thread schreibt, ein anderer liest. Vorteil: Speed, da keiner warten muß. Nachteil: Wenn mehrere Threads lesen, muß das Lese-Interface leider doch mit einem Lock versehen werden.
stichwort snapshot - wobei der begriff synchronisationsfrei nicht ganz korrekt ist, ohne synchronisation geht es nähmlich nicht. korrekt wäre hier lock- oder wait-free. es gibt mittlerweile diverse brauchbare lock-freie algorithemn für datenstrukturen, die deutlich besser als die üblichen lock-basierten implementierungen sind (insbesondere wenn viele threads um dieselbe resource konkurrieren). aber wie gesagt, gänzlich ohne synchronisierung geht es nicht - bei diesen algorithmen tauscht man den mutual exclusive lock gegen memory barriers, die auch nicht ganz billig sind.