[gelöst] Ist QList.size() Thread-Safe?

Alles rund um die Programmierung mit Qt
Antworten
Zorki
Beiträge: 3
Registriert: 11. März 2010 17:14

[gelöst] Ist QList.size() Thread-Safe?

Beitrag von Zorki »

Hallo zusammen,

ich verarbeite ein paar Daten von der Festplatte nach dem Producer-Consumer-Pattern und einer zwischengeschalteten QQueue.
Für das Einfügen und Extrahieren von Elementen nehme ich einen Mutex, allerdings wollte ich wissen,
ob ich das für einfache Abfragen - im konkreten Fall queue.size() - auch brauche.

Viele Grüße
Zorki
Zuletzt geändert von Zorki am 27. September 2010 17:05, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Die Doku beantwortet deine Frage. Such ganz oben diesen Hinweis:
Note: All functions in this class are reentrant.
Auf das reentrant kann man klicken, dann gibts Info dazu.
Zorki
Beiträge: 3
Registriert: 11. März 2010 17:14

Beitrag von Zorki »

... Hab ich wohl überlesen.
Allerdings verstehe ich noch nicht ganz, wieso ich Probleme haben sollte size() zu benutzen, da ja kein Speicher verändert sondern nur gelesen wird.
So wie ich das sehe könnte es höchstens passieren, dass ich keine ganz aktuelle Größenangabe bekomme.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Zorki hat geschrieben:So wie ich das sehe könnte es höchstens passieren, dass ich keine ganz aktuelle Größenangabe bekomme.
Und dieses "höchstens" kann verdammt große Probleme hervorrufen. Wenn deine Liste schrumpft, nachdem du size() aufgerufen hast, und dann auf einen ungültigen Index zugreifst. Oder bei einer Iteration über alle Elemente zur Auswertung das letzte Element nicht mehr mit einbeziehst? Das sin schon gewaltige Probleme, die mit unter dein Programm crashen lassen.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Und dieses "höchstens" kann verdammt große Probleme hervorrufen. Wenn deine Liste schrumpft, nachdem du size() aufgerufen hast, und dann auf einen ungültigen Index zugreifst. Oder bei einer Iteration über alle Elemente zur Auswertung das letzte Element nicht mehr mit einbeziehst? Das sin schon gewaltige Probleme, die mit unter dein Programm crashen lassen.
Eigentlich sind dies keine Probleme im Zusammenhang mit multithreaded funktionen, weil er eben in dem geschilderten Fall sowieso auf diesen Fall expliziet reagieren muss.
Das heisst er muss im oben genannten Fall einen kompletten Block an Code in eine critical Section hängen, egal ob die Funktion nun reentrant iss oder nicht.

das reentrant hingegen erlaubt es, die Abfrage eben auch ohne (eigenen) Schutz zu machen. Man muss halt nur damit rechnen, dass man wenn die funktion zurueckkomt, das ergebniss schon "veraltet" sein kann.
Fuer Code der absolute aktualitaet vorraussetzt, sind also reentrante funktionen ohne eigenen Schutz nichts. Aber sie sind halt gut geeignet um z.b. fortschritte zu melden, oder vorab anfragen, wo das ergebnis bei einer Direkten operation eh nochmal ueberprueft wird.

"Reentrant" garantiert Dir nichtmal das du ein Ergebniss erhaelst, was irgendwann mal aktuell war, es kann im Kollisionsfall selten auchmal "Müll" liefern. Aber es garantiert, das du durch die Abfrage das Object nicht durcheinanderbringst, in einen undefinierten zustand versetzt, so dass du eben selbst die möglichkeit hasst zu entscheiden, iss das ergebniss wichtig, dann brauch ich schutz, -> kostet performance, oder iss das ergebnis "unwichtig".

Ja es gibt auch (relativ) unwichtige Ergebnisse !
Fortschrittsbalken z.b.
oder useranzeigen, die sich mehrmals pro sekunde aktualisieren, da iss es ned sooo tragisch, wenn ab und an mal nen Ausrutscher bei ist.

@TE
wenn du MT programmierst, solltest Du dich wirklich mit den Begriffen:
atomar,
reentrant (in bezug auf funktionen/Methoden/operationen),
threadsafe (in Bezug auf Objecte/ganze Bibliotheken)
auskennen, vor allem was sie genau bedeuten. Falls man die falsch deutet, wird man so auf die Nase fallen ....
grad "threadsicher" wird sehr sehr gern falsch gedeutet :-), bzw auch von vielen falsch verwendet.

Ciao ...
Zorki
Beiträge: 3
Registriert: 11. März 2010 17:14

Beitrag von Zorki »

Vielen Dank für die Antworten, ich weiß jetzt zumindest, woran ich bin.

In meinem Fall spielt das aber tatsächlich keine Rolle, da ich mit size() im Producerthread abfrage,
ob die maximale Puffergröße erreicht ist.
Da ich nur einen Producer haben kann der Wert also höchstens zu groß sein,
und mehr als mal unnötig warten kann folglich nicht passieren.
Antworten