queue & threadsafe
-
einen wunderschönen guten morgen!
ich möchte mit zweier threads eine queue befüllen bzw. löschen und zwar folgend:
1. thread ruft nur die push methode auf
2. thread liest mittels front und löscht anschließend per popsoweit mir bekannt ist, sind alle STL container alles andere als threadsafe oder lieg ich da falsch?
die einfachste lösung wäre ein locking aber da müsste ich für meine 2 vorgänge (schreiben bzw. lesen&löschen) immer einen write bzw. expliziten lock machen und irgendwie find ich diese blockierung zuviel des guten, da ich ja nur an das ende schreibe und am anfang was lese/lösche.
hat dazu wer gute überlegungen, wie man einigermaßen gleichzeitig schreiben und lesen/löschen kann mittels einer queue?
danke für eure hilfe!
-
Du könntest die Queue in eine Klasse als Attribut packen und mit einem Mutex threadsicher dann machen.
Du wrappst / nutzt das Fassade-Pattern
und implementierst front(), push() und pop() neu, und in diesen Methoden rufst du dann zu Beginn
Mutex.Lock()
und am Ende
Mutex.Unlock()
auf oder nutzt gleich einen entsprechenden Guard
-
und genau das möchte ich nicht machen, weil ich durch diesen expliziten lock die threads gegenseitig blockiere.
wenn man sich jetzt generel die queue logik ansieht (fifo verfahren), dann dürfte es für die queue ja keine problem sein ohne lock für meine aufgabenstellung threadsafe zu sein, da ja nur EIN thread das pop macht und der andere nur das push.
mir geht es nur darum, dass ich einen datentransfer von einem thread in den anderen thread machen möchte, wo ich so wenig wie möglich gegenseitige blockierung habe.
-
Leider kannst du dir ja nicht sicher sein, dass die queue so funktioniert. Du kannst dir natürlich deine queue Implementierung ansehen und dann entscheiden, aber wenn das Programm mal mit einer anderen Version kompiliert wird hilft das auch nichts.
Was spricht dagegen, eine queue neu zu implementieren?
Die dann natürlich ohne locking auskommt.jenz
-
taff schrieb:
wenn man sich jetzt generel die queue logik ansieht (fifo verfahren), dann dürfte es für die queue ja keine problem sein ohne lock für meine aufgabenstellung threadsafe zu sein, da ja nur EIN thread das pop macht und der andere nur das push.
Da wär ich mir nicht so sicher. Ich kenn dir Implementierung der Queue auch nicht. Aber ich gehe davon aus, dass sie interne Variable (vielleicht cursor oder so) enthält, die für den Zugriff nötig sind.
Und wenn du da einmal reinpfuschst, während dein anderer Thread darauf zugreift hast du schon verloren.
-
@DarthZiu:
war mein fehler, ich meinte einfach die generelle theoretische queue logik (nicht die spezielle der stl)@jenz2
ja das wäre eine idee sich selbst eine threadsafed queue zu machen, nur die frage ist, ob ich selbst dies so threadsicher entwickln kann und man nicht dann doch wieder zu einem zustand kommt, der mehr als sehr sehr kritisch sein könnte....eigentlich müsste mein problem schon von sehr vielen programmieren gelöst worden sein. ein thread empfängt daten und ein anderer arbeitet diese daten ab und die beiden threas sollten sich so wenig wie möglichst gegenseitig blockieren ... hmmmm
-
Wieso sollten sich die Threads gegenseitig blockieren wenn Du vor dem push (pop) lockst und nachher wieder unlockst?! Muss die Queue die Daten abtippen? Ausserdem um sich zu blockieren, muss schon der unwahrscheinliche Fall eines gleichzeitigen Aufrufs vorliegen, und dann ist einer der beiden Threads halt für ein paar ns blockiert. Das ist aber der Sinn der Synchronisation
Auf der anderen Seite, wie würdest Du bei einer selbstgeschriebenen Queue die Synchronisation erreichen? Genau, indem Du verhinderst dass jemand in zwei Methoden gleichzeitig Verwaltungsdaten manipuliert. Und dafür nimmt man z.B. Mutexe.
Im Prinzip kommen also eh alle Vorschläge auf das gleiche raus...
-
Naja, bei ner Queue könnte ich mir dass schon so vorstellen:
- Queue ist eine Liste (von Objekten, die den benötigten Datentyp kapseln)
- Zeiger auf den Kopf (darf nur von einem Leser benutzt werden)
- Zeiger auf das Ende (darf nur von einem Schreiber benutzt werden)Das könntest du dann parallel benutzen, aber ansonsten stimme ich LordJaxom zu. Genau so (Mutexe) wird es schon immer realisiert und der Overhead durch das Blockieren ist wirklich gering.
-
also zu einem gegenseitigen blockieren wird es sicher kommen, da ich über ein gbit-netzwerk daten empfange und diese dann verarbeite und auch wieder verschicke, und irgendwie glaub ich doch, dass die blockierung häufig vorkommen wird.
wie gering das locking ausfällt wird aufkommen, da es ja auch nicht unwichtig ist, wieviele daten ich bei einem locking vorgang auf einmal abarbeite usw. usf.
-
hier könnt ihr was lesen: http://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf