Dynamische Semaphore
-
Hallo Leute,
ich habe ein ziemliches hardcore problem. Also- ich habe eine Klasse A, die beinhaltet ein std::set von pointern auf instanzen einer klasse B
- Von aussen wird auf die Instanzen von B zugegriffen mittels iteratoren
- Es soll möglich sein, parallel auf die verschiedenen instanzen von B zuzugreifen, aber es soll immer nur ein thread gleichzeitig auf die gleiche instanz von B zugreifen können (bis hierhin würde ich B einfach ein semaphor als attribut geben, aber es geht ja noch weiter)
- Jetzt soll man Instanzen von B löschen können (über eine Methode von A) Dazu müsste natürlich A auch den semaphor der instanz blockieren, sodass kein iterator zugreifen kann, nachdem der speicher schon freigegeben ist
- Die Iteratoren haben ein flag und tragen sich in eine Liste ein, sodass man die problemlos benachrichtigen kann, wenn ein element gelöscht wird - dann können die im kritischen bereich erst mal prüfen ob ihr flag gesetzt ist und in dem fall eben nicht mehr zugreifen, sondern ne exception werfen oÄ
Das Problem ist jetzt, dass ja noch Iteratoren am warten sein können, während die lösch-methode schon die instanz löscht. Die kriegen zwar das Flag gesetzt, aber da der semaphor ja attribut von B ist, wird der ja zusammen mit der instanz gelöscht und muss vorher noch an sem_destroy übergeben werden. Wenn die wartenden threads dann einfach weiter laufen würden, sobald das passiert, wäre alles in ordnung, aber die sem_destroy dokus sagen, dass das nicht passiert, sondern dann wird der zustand der wartenden threads "undefiniert"...
Einen globalen Semaphor zu nehmen kommt nicht in frage, weil man dann gleich ohne multithreadding arbeiten kann (dann bringt das ganze nix).
Ich habe schon darüber nachgedacht, die semaphore in einer anderen struktur zu speichern, aber dann muss man wieder mit nem globalen semaphor die andere struktur schützen -> wieder kein gewinn durch multithreadding...
einen int-zähler zu benutzen um threads davon abzuhalten, mit dem warten zu beginnen und erst löschen nachdem der letzte wartende thread durch ist, sollte auch nicht funktionieren, da der int 1. auch wieder durch einen semaphor geschützt werden müsste und 2. weil der int mit der instanz mitgelöscht werden müsste und das wieder abstürze geben müsste, wenn danach threads anfangen wollen zu warten...
sem_unlink klingt brauchbar, ist aber wohl nur für benannte semaphore (die über eine datei funktionieren)
Ich habe aber davon gelesen, dass man den wartenden threads mit einem interrupt oder signal oder so mitteilen kann, dass sie aufhören sollen zu warten. Das müsste funktionieren, nur wie geht das? dazu habe ich nichts gefunden... und was mache ich eigentlich, wenn andere iteratoren anfangen auf die gelöschte instanz zu warten NACHDEM schon die benachrichtigt wurden, die vorher schon am warten waren?
Wie gesagt ist das ein ziemliches hardcore problem, aber das projekt soll eben qualitativ höchste Ansprüche erfüllen, damit man es bedenkenlos überall einsetzen kann...
Vielen Dank schonmal!
AlgoMan
-
Ich sollte vielleicht hinzufügen: natürlich muss ich einen semaphor für das set benutzen, wenn ich da sachen draus löschen will - der wäre in diesem szenario global, aber die eigentliche datenstruktur hat mehrere sets und die iteratoren auf dem einen set können problemlos weiterlaufen während ein anderes set verändert wird.
Ich wollte die situation nur so einfach wie möglich darstellen und da ist es wohl ein bisschen ZU einfach geworden (soweit man das bei einer hardcore frage wie dieser so nennen kann
)
-
Wie du selbst siehst, hat deine Realisierung diverse Maengel. Am besten du ueberdenkst nochmal das uebergeordnete Problem und vergisst deinen praesentierten Loesungsansatz.
-
Hallo AlgorithMan,
vieleicht helfen dir boost::shared_ptr weiter ...
Gruß Frank
-
Also neu schreiben möchte ich das Ganze eigentlich nicht, da ich schon recht viel Code geschrieben habe und die Datenstruktur an sich eigentlich auch für alternativlos halte (zumindest wenn man damit so viele Anwendungsgebiete abdecken können soll, wie ich es vorhabe)
Aber selbst wenn ich das komplett neu schreiben WÜRDE, trotzdem sollen ja mehrere Threads parallel auf verschiedene B's zugreifen können und trotzdem sollen ja B's löschbar sein, also komme ich zwangsläufig wieder in die Situation, dass einige Threads noch auf das B warten könnten, das gerade gelöscht wird...
Irgendwie muss ich auch dann in der Lage sein, wartenden Threads mitzuteilen, dass sie das Warten abbrechen sollen und dass keine neuen Threads anfangen sollen, zu warten...
-
Also ich habe mir gerade mal bei Amazon das Buch "Programming with POSIX Threads" von David R. Butenhof bestellt. 65€ sind zwar kein Pappenstiel, aber ich habe vielerorts gelesen dass es DAS Buch für Multithreadding ist...
Danach sehen wir weiter