Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Strings thread-safe übergeben (https://www.delphipraxis.net/164117-strings-thread-safe-uebergeben.html)

jus 28. Okt 2011 23:16

Strings thread-safe übergeben
 
Hallo,

ich möchte paar Sachen in mehreren Threads auszulagern. Ich möchte aber in meinem Hauptprogramm von Threads auch Strings empfangen können. Da komme ich zu der grundsätzlichen Frage, wie empfängt man sauber, sprich thread-safe, im Hauptprogramm Strings von mehreren laufenden Threads? Bisher habe ich im Thread mit Postmessage Integer Werte zum Hauptprogramm verschickt, doch wie verschickt man Strings threadsafe?

lg,
jus

Medium 28. Okt 2011 23:33

AW: Strings thread-safe übergeben
 
Strings, bzw. alles an nichtelementaren Typen, übergebe ich sehr gerne über Listen. Dem Thread also in deinem Fall einfach eine TSringList-Property mitgeben, an die der Thread selbst nur anhängt, aber nie selber etwas draus löscht bzw. ändert. Bei einem neuen Eintrag eine Windows-Message an alles was so zu benachrichtigen wäre verschicken, und dort dann lesen und löschen. (Bietet zudem die Option, eine LIFO oder FIFO Queue zu basteln.)
Grad bei Objekten mache ich es zudem ganz gerne so, dass ich zunächst eine lokale Arbeitsinstanz im Thread erstelle, diese komplett vorbereite, und dann das TList.Add() in einer CriticalSection erledige, so dass auch die letzte knall-gefährliche Ecke raus ist, und ich nicht auf die Implementierung von TList angewiesen bin threadsafe Add() zu haben. (Ich hab's aber auch ohne CS noch nie kaputtgehen sehen.)
Hat vor allem den Vorteil, dass ein zeitweise ausgebremster "Abholer" sobald wieder Luft ist alles verpasste in der richtigen Reihenfolge nachholen kann. Ob das wünschenswert ist, oder ob man sowas lieber skipped ist dann wieder vom konkreten Fall anhängig.

Bei der Übergabe zwischen zwei Threads übergehe ich dann noch ganz gern die Messages, und habe im Empfänger-Execute sowas stehen:
Delphi-Quellcode:
procedure TRecipientThread.Execute;
begin
  repeat
    if JobObjectList.Count > 0 then
    begin
      CurrentJobObject := JobObjectList[0];
      DoAllKindsOfStuffWith(CurrentJobObject);
      JobObjectList.Delete(0); // Das ist ne TObjectList mit OwnsObjects = true, daher kein .Free hier.
    end;
  until Terminated;
end;
Sowas ist im Thread der MainForm eher unpraktisch, daher dahin lieber die Messages.

Einzig unschöne daran ist, dass der Objektersteller nicht der Zerstörer ist, was mindestens einen entsprechenden Kommentar im Code bedarf. Aber ohne GC würden mir da wenige andere gute Wege einfallen, ausser die Gegenrichtung genau so zu gestalten: Nachricht an Thread: "Lösche bitte gleich deinen ersten Listeneintrag." - konsequenter, aber irgendwie auch nicht so wirklich viel schöner.

Sir Rufo 28. Okt 2011 23:41

AW: Strings thread-safe übergeben
 
Wenn die Übergabeliste eine TObjectList (OwnsObjects) dann ist das nicht unschön.
Die Objekte werden beim Abholen aus der TObjectList dort entnommen (Extract), also die Zuständigkeit übernommen.

Somit können auch keine Speicherlecks entstehen.

Medium 28. Okt 2011 23:55

AW: Strings thread-safe übergeben
 
Extract ist auch fein, stimmt. Dann am besten noch über eine Property "NextObject", so dass der Abholer nichtmals mehr den Fehler machen kann nur die Referenz zu kopieren, und nicht zu Extracten. (Die Liste selbst also Private.) Das klingt noch runder, danke :)

jus 30. Okt 2011 19:31

AW: Strings thread-safe übergeben
 
Wiedermal was dazugelernt. :thumb: Vielen Dank für eure Antworten!

Lg,
jus


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz