AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Thread sichere Datenabfrage

Ein Thema von Kishmet · begonnen am 29. Okt 2020 · letzter Beitrag vom 30. Okt 2020
Antwort Antwort
Kishmet

Registriert seit: 29. Okt 2020
Ort: Großraum Stuttgart
43 Beiträge
 
Delphi 12 Athens
 
#1

Thread sichere Datenabfrage

  Alt 29. Okt 2020, 09:54
Guten Morgen,

(Falls dieses Thema zweimal auftaucht tut es mir leid, mein erster Versuch Wollte nicht so richtig, kann aber sein das er doch noch durchrutscht)

Ich arbeite jetzt seit zwei Jahren mit Delphi (derzeit 10.4.1) und bin nun das erstemal an einem Punkt an dem ich nicht recht weiter komme und auch Online finde ich grade entweder nicht die richtigen Schlagworte oder habe einfach Verständniss Probleme...

Das Drumherum:

Ich habe einen Mainthread der Daten von einem Gerät ausliest und diese sowohl auf dem Monitor darstellt als auch immer hinten an eine Datei anhängt. (eigentlich sind das mehrere threads aber das tut soweit)

Nun habe ich einen zweiten Thread gebastelt, der diese Daten einließt (wirklich nur liest) und auswertet. Dann schreibt er die Ergebnisse in eine andere Datei. Wenn ich in der Messung zurückScrolle sollten dann diese Ereignisse auch vom Main thread ausgelesen und dargestellt werden können. Da die Ergebnisse Variieren lese und werte ich immer alles ein/aus. Das könnte man ändern wäre aber sehr aufwendig und ich bin mir nicht sicher ab das am generellen Problem etwas ändert.

Mein basis Problem:

Manchmal kommt es bei mir zu einer Art Integerüberlauf - ich habe bisher noch nie Zugriffsverletzungen oder derlgeichen bekommen und bin mir nicht sicher woran es liegt.
Delphi-Quellcode:
 
DieKlasse = class
private
  FDataReader : TMyBufferedFileReader;
  FReadDataValueNum: Int64;
  //... und andere
end;

Function DieKlasse.ReadInData(var Abuf: TMyData):Cardinal;
var
  idx: Int64;
begin
  if FReadDataValueNum >= FDataReader.ValueCount then
  begin
    idx := FReadDataValueNum - FDataReader.ValueCount;
    if idx < length(FOnlineWriteCache) then
    begin
      ABuf := FOnlineWriteCache[idx]; //Hier entsteht der fehler(sehr sporadisch) wenn idx zu groß wird (was ja aber eigentlich gar nicht sein kann)
      result := 1;
    end else begin
      result := 0;
    end;
  end else begin
    FDataReader.ValueNumber := FReadDataValueNum;
    result := FDataReader.Read(ABuf, 1);
  end;
end;
1. Ich bin mir immernoch nicht ganz sicher ob einfaches Lesen beim Multithreading ein Problem darstellt?? Ob dabei Müll rauskommt wäre mir an der Stelle auch egal, das Fange ich Ohnehin ab. Aber stellt das Prinzipiell ein Problem dar?

2. Muss ich die Abfragen der Streams in critical Sections packen oder gibt es hier befehle (vorgefertigt) die das Lesen und schreiben bereits Threadsicher machen? Alla: "ReadThisFileAndLockItWhileDoingSo"

3. Wenn ich Critical sections einführe sperren diese dann auch alle Variablen/Dateien usw. die ich innerhalb dieser Section verwende?

Über ein wenig Rat wäre ich super dankbar. Das Thema Threads ist mir einfach immernoch nicht 100% geheuer.

Lieben Gruß
Kishmet

PS: Vielen dank für das Tolle Forum und die Tollen Beiträge vom harten Kern! Ihr seit echt Spitze und ich hab schon soooo viel von euch gelernt!

Geändert von Kishmet (29. Okt 2020 um 11:30 Uhr)
  Mit Zitat antworten Zitat
Kishmet

Registriert seit: 29. Okt 2020
Ort: Großraum Stuttgart
43 Beiträge
 
Delphi 12 Athens
 
#2

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 11:08
hm... also hier mal meine Gedanken zu dem Thema:

wenn FReadDataValueNum >= FkanalDatareader.ValueCount ist, dann kann folglich in der nächsten Zeile idx nicht negativ oder zu groß werden. Außer ein anderer Thread ändert just in dem Moment den ValueCount.... Korrekt? Ist die Einzige logische Erklärung die mir noch einfällt.... Wobei er eigentlich auch nicht zu groß werden kann da ich das ja wiederum abfrage und dann eh raus bin... Noch dazu tritt das nur sporadisch auf, daher ist es so schwer für mich zu kontrollieren was tatsächlich drin steht...

Geändert von Kishmet (29. Okt 2020 um 11:28 Uhr) Grund: Hirnverdrehungen vom zuvielen starren
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 11:20
Herzlich willkommen.

Konkret helfen kann ich nicht, aber falls Du die Kanäle nicht kennst, dann schau Dich mal dort noch um:
https://www.youtube.com/user/EmbarcaderoGermany/videos
https://www.youtube.com/c/Embarcader...ologies/videos

PS: Trage mal noch Deine Delphi-Version in Deinem Profil ein.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Kishmet

Registriert seit: 29. Okt 2020
Ort: Großraum Stuttgart
43 Beiträge
 
Delphi 12 Athens
 
#4

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 12:07
Zitat:
Überall muß um alles, was auf diese Variablen zugreift, die selbe CriticalSection (oder Ähnliches, z.B. siehe Delphi-Referenz durchsuchenSyncObjs).
Puh Das würde ne mittlere Katastrophe geben. Da der reader an sich abgeleitet ist, Unterfunktionen hat und auf diesen an unzähligen stellen zugegriffen wird. Kann man die critical Section denn auch außerhalb des Threads deklarieren, also bpsw. direkt im Reader der ja universell einsetzbar ist? Ich habe das bisher nur im Create bzw. im Execute des Threads gesehen(in den Beispielen die ich zu dem thema gefunden habe)... Wenn ich die Section aber im Objekt (also im Reader) erzeugen könnte wäre das vermutlich, zumindest gefühlt, einfacher.

Zitat:
Nur Lesend, wenn währenddessen nirgendwo Schreibend zugegriffen werden kann, da kann man es auch ohne Synchronisation machen, aber nur wenn beim Lesezugriff nichts geschrieben wird.
z.B. Stream.Read ist ein schreibender Zugriff, da dort der Posiotionszeiger verändert wird.
Das war mir so tatsächlich noch nicht ganz klar. Jetzt muss ich tatsächlich sagen das ich überrascht bin das es überhaupt läuft... Vielleicht steckt da auch schon irgendwo ne critical Section die ich noch nicht gefunden habe. Ich mach mich mal auf die Suche.

Zitat:
Konkret helfen kann ich nicht, aber falls Du die Kanäle nicht kennst, dann schau Dich mal dort noch um:
Links zu guten Videos sind immer gold wert. Die hier kenn ich zwar schon, aber ich hab für dieses Problem dort tatsächlich noch nicht gesucht... Danke dir

Jetzt nochmal eine Frage von Oben, die ist noch nicht so richtig beantwortet worden glaube ich:

Gibt es eine Lese bzw. eine Schreibfunktion in der von Haus aus eine Lock integriert ist? und erst wenn das Fertig ist, kann ein anderer thread wieder darauf zugreifen?
  Mit Zitat antworten Zitat
reaktor

Registriert seit: 1. Aug 2012
11 Beiträge
 
#5

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 13:52
Hallo.
Ein mMn sehr guter Beitrag zum Thema Synchronisation von Bernd Ua:
Video:
https://www.youtube.com/watch?v=WOc89TF8l-8
Material:
http://probucon.de/wp-content/upload...ronisation.pdf

Zitat:
Gibt es eine Lese bzw. eine Schreibfunktion in der von Haus aus eine Lock integriert ist? und erst wenn das Fertig ist, kann ein anderer thread wieder darauf zugreifen?
Neben Critical Sections, TMonitor und vielen anderen gibt es noch eine threadsichere Warteschlange: TThreadedQueue.
Beispiel dazu hier:
http://chee-yang.blogspot.com/2015/1...eadsynchronize

Evtl ist auch TMultiReadExclusiveWriteSynchronizer für dich der richtige Weg.
Auszug aus dem o.g. PDF:

TMultiReadExclusiveWriteSynchronizer :
• Verwaltet mehrere lesende Zugriffe und
blockierenden Schreibzugriff
• BeginRead/EndRead zum Lesen
• BeginWrite/EndWrite zum Schreiben
• Zum Beispiel verwendet von der VCL via
IReadWriteSync in Forms (GlobalNamespace)

In dem Buch "Delphi Cookbook" gibt es, glaube ich, ein Beispiel für ein Oszilloskop was auf Multi-Threading basiert. Die Problemstellung klang jetzt auf Anhieb irgendwie ähnlich.

Tut mir leid, dass ich keine konkretere Hilfe anbieten kann.
  Mit Zitat antworten Zitat
Kishmet

Registriert seit: 29. Okt 2020
Ort: Großraum Stuttgart
43 Beiträge
 
Delphi 12 Athens
 
#6

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 14:10
hihi das video hab ich grade auf. Danke dir @Reaktor

Mein größtes Problem ist grade tatsächlich auch das generelle Verständniss, was aber vermutlich einfach daran liegt das der Code in dem ich arbeite schon die eine oder andere zeile hat... und davon auch einfach viel nicht von mir ist, sondern von jemandem den ich deswegen auch nicht mehr fragen kann...

Zitat:
Evtl ist auch TMultiReadExclusiveWriteSynchronizer für dich der richtige Weg.
Das hört sich interressant an. Das muss ich mir mal ansehen.

Prinzipiell sollte es auch bei mir irgendwo in der Nähe des Codes zum schreiben und lesen bereits etwas geben was die threadsicherheit garantiert. Denn es geht ja auch das Rückblättern schon, wäre das nicht sicher dürfte auch dieser Teil nicht richtig funzen, ich bin leider bisher nicht dahinter gekommen, wie das genau funktioniert: Da keine critical section, Monitor synchronize oder sonstiges aufgerufen wird, ist das für mich grade nicht ganz plausibel... Das einzige was mir auffällt ist das die Lese und Schreib Prozesse über Pointer verbogen werden o.O . Vielleicht liegt es aber auch daran das die Datei jeweils zwischen gebuffered wird. So richtig Sinn bekomme ich in die Sache nur leider heute iwie nicht rein...

Zitat:
In dem Buch "Delphi Cookbook" gibt es, glaube ich, ein Beispiel für ein Oszilloskop was auf Multi-Threading basiert. Die Problemstellung klang jetzt auf Anhieb irgendwie ähnlich.
Prinzipiell ist es mehr oder minder genau das was ich gerade Bastel. Ein Oszi in dem Zurückgespult werden kann und das gleichzeitig das Signal auswertet. Was mich gerade iritiert ist das es läuft - Denn himitsu hat recht, das lesen und schreiben sollte sich eigentlich beißen... naja. Ich werde mir das Buch mal holen, verkehrt ist das sicherlich nicht.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.372 Beiträge
 
Delphi 12 Athens
 
#7

AW: Thread sichere Datenabfrage

  Alt 29. Okt 2020, 11:19
Überall muß um alles, was auf diese Variablen zugreift, die selbe CriticalSection (oder Ähnliches, z.B. siehe Delphi-Referenz durchsuchenSyncObjs).


Nur Lesend, wenn währenddessen nirgendwo Schreibend zugegriffen werden kann, da kann man es auch ohne Synchronisation machen, aber nur wenn beim Lesezugriff nichts geschrieben wird.
z.B. Stream.Read ist ein schreibender Zugriff, da dort der Posiotionszeiger verändert wird.

Auch Lesend auf eine String-Variable oder Interface-Zeiger zugreifen ist ein schreibender Zugriff,
aber die Referenzzählung ist mit den nachfolgend erwähnten atomaren Operationen gelöst.



Zuweisen/Ändern von Integern/Pointer, da gibt es auch die Möglichkeit von "atomaren" Zugriffen durch die CPU,
siehe MSDN-Library durchsuchenInterlockedAdd und Auslesen geht ohne Extrafunktion (siehe "nur Lesend", da die CPU während des Schreibens alles blockt).

Mehrfach auf den "selben" Wert zugreifen, dann vorher in eine lokale Variable kopieren.
z.B. if myvar > 0 then MachwasMit(myvar);

nur Windows: Bei Google suchenInterlockedIncrement
ansonsten siehe Delphi-Referenz durchsuchenTInterlocked.Increment bzw. die neuen platformübergreifenden Delphi-Referenz durchsuchenAtomicIncrement
oder LOCK im Assembler. https://www.felixcloutier.com/x86/xadd https://stackoverflow.com/questions/...n-x86-assembly
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (29. Okt 2020 um 11:25 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz