Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Zugriff mehrerer Threads aufeinander (https://www.delphipraxis.net/175342-zugriff-mehrerer-threads-aufeinander.html)

milchbrötchen 13. Jun 2013 16:11

Zugriff mehrerer Threads aufeinander
 
Hallo zusammen,

ich habe zwei verschiedene Threadklassen, von denen es in jeweils einem Array (array1, array2) beliebig viele geben kann. Nun soll jeder Thread in array1 jedem beliebigen Thread in array2 eine Aufgabe in die Liste schreiben können und umgekehrt auch jeder Thread in array2 jedem Thread in array1.

Code:
  taufgabensorte1 = class(tthread)
    private
      liste: tstringlist;
    ...

  taufgabensorte2 = class(tthread)
    private
      liste: tstringlist;
    ...

  talleaufgaben = class
    private
      array1: array of taufgabensorte1;
      array2: array of taufgabensorte2;
    ...
Ich komme aber irgendwie nicht drauf, wie man so etwas vernünftig (und professionell) umsetzen soll.

Vielen Dank für eure Ideen :)

Der schöne Günther 13. Jun 2013 16:16

AW: Zugriff mehrerer Threads aufeinander
 
Mir persönlich wären diese Abhängigkeiten zu gruselig - Ich kenne eigentlich immer nur das Konzept eines Dispatchers der zu erledigende Aufträge in Erfahrung bringt und daraufhin Worker-Threads erstellt und sie mit den entsprechenden Informationen für die Aufgabenerledigung füttert.

Die zum Speicherschutz bei mehreren Threads gängigen Objekte wie
Delphi-Quellcode:
TCriticalSection
oder
Delphi-Quellcode:
TMultiReadExclusiveWriteSynchronizer
kennst du?

Klaus01 13. Jun 2013 16:18

AW: Zugriff mehrerer Threads aufeinander
 
Hallo,

wodurch unterscheiden sich Thread1 und Thread2?
Was bezweckst Du damit?

Wäre es nicht sinnvoller einen Threadpool zu haben der sich Aufgaben aus einer zentralen Liste holt?

Grüße
Klaus

Furtbichler 14. Jun 2013 07:05

AW: Zugriff mehrerer Threads aufeinander
 
Zitat:

Zitat von milchbrötchen (Beitrag 1218540)
...von denen es in jeweils einem Array (array1, array2) beliebig viele geben kann. ...

Sachma, was für eine CPU hast Du denn? :shock:

So kann man das imho am einfachsten lösen:

Delphi-Quellcode:
Procedure TMyThread.AddToList (const task : String);
Begin
  MyCriticalSection.Enter;
  Try
    MyStringList.Add(task);
  Finally
    MyCriticalSection.Leave;
  End
End;

Function TMyThread.GetNextTask : String;
Begin
  MyCriticalSection.Enter;
  Try
    If MyStringList.Count = 0 then
      Result := ''
    else begin
      Result := MyStringList[0];
      MyStringList.Delete(0);
    end
  Finally
    MyCriticalSection.Leave;
  End
End;

milchbrötchen 14. Jun 2013 11:57

AW: Zugriff mehrerer Threads aufeinander
 
also um das mal näher zu beschreiben:

taufgabensorte1 ließt sekündlich Daten aus etwa 50 Geräten von Typ 1 aus (anders als mit Polling gehts leider nicht). Damit, wenns bei einem Gerät mal stockt, nicht auch alle anderen Leseoperationen stocken, habe ich mich für Threads entschieden (und nicht einfach nacheinander abfragen). Es können auch Werte in ein Gerät geschrieben werden.

taufgabensorte2 macht genau das gleiche mit etwa 10 Geräten von Typ 2 (völlig verschieden zu Typ 1, deswegen auch ganz anderes Threaddesign).

Wenn jetzt bestimmte Daten aus einem der Geräte von Typ 1 gelesen wurden, sollen diese in ein (oder auch mehrere) definierte(s) Gerät(e) von Typ 2 geschrieben werden. Also sollte dann in die Aufgabenliste des jeweiligen Threads geschrieben werden, was geschrieben werden soll, damit dieser dies im nächsten Durchlauf machen kann. Und das gleiche nochmal umgekehrt mit Daten von Geräten Typ 2 nach Typ 1.


P.S. Criticalsection ist mir bekannt.

Der schöne Günther 14. Jun 2013 12:13

AW: Zugriff mehrerer Threads aufeinander
 
Etwas vielleicht vergleichbares hatte ich neulich auch. Erst wollte ich auch für jedes Gerät einen eigenen (relativ langsam laufenden) Watchdog-Thread aufsetzen.

Davon bin ich aber sehr schnell wieder abgesprungen, es wurde pro Anschluss ein einziger Thread, der alle auf dem Bus liegenden Geräte pollt. Bist du dir überhaupt sicher, dass du einfach parallel kommunizieren kannst wenn die Kommunikationsroutinen blockierend sind? Im Fall des seriellen Anschlusses beispielsweise blockieren andere Threads trotzdem wenn gerade ein Aufruf in einem anderen Thread hängt. Das nur als Hinweis.


Als zweiten Punkt möchtest du auf die eingelesenen Daten reagieren. Ich bleibe weiterhin dabei, dass sich die Threads für Gerätetyp auch kein Stück mit anderen (artfremden) Threads herumschlagen sollten. Du hast einen oder mehrere Threads, die sich um Informationsbeschaffung durch Polling kümmern. Die in Erfahrung gebrachten Werte werden in die entsprechenden Eigenschaften des Objekts geschrieben.
Das Objekt ließe sich weiterhin so einrichten, dass bei einem Aktualisieren der Werte Aktionen ausgeführt werden, beispielsweise eine Methode aufgerufen werden, die sich darum kümmert, welche neuen Informationen für die Geräte des Typs 2 sich daraus ergeben und geschrieben werden sollen. Diese Werte lassen sich in (wieder einen!) Thread für Typ 2 in eine Liste anhängen, was er in seinem nächsten Durchgang schreiben soll.

sx2008 14. Jun 2013 12:22

AW: Zugriff mehrerer Threads aufeinander
 
Zitat:

Zitat von milchbrötchen (Beitrag 1218594)
taufgabensorte1 ließt sekündlich Daten aus etwa 50 Geräten von Typ 1 aus

...und sichert die Daten in eine Queue.
Zitat:

Zitat von milchbrötchen (Beitrag 1218594)
taufgabensorte2 macht genau das gleiche mit etwa 10 Geräten von Typ 2

Eine weitere Queue für die Empfangsrichtung.
Zitat:

Zitat von milchbrötchen (Beitrag 1218594)
Wenn jetzt bestimmte Daten aus einem der Geräte von Typ 1 gelesen wurden, sollen diese in ein (oder auch mehrere) definierte(s) Gerät(e) von Typ 2 geschrieben werden. Also sollte dann in die Aufgabenliste des jeweiligen Threads geschrieben werden

Da haben wir dann nochmal 2 weitere Queues für die Senderichtung.

Du brauchst also threadsichere Queues (first-in-first-out).
Hierzu könnte man die Klasse
Delphi-Quellcode:
TThreadList
verwenden.
Das Grundgerüst sieht so aus:
Delphi-Quellcode:
TThreadObjectQueue = class(TObject)
private
  FList : TThreadList;
public
  constructor Create;
  destructor Destroy;override;
  procedure Push(value:TObject);
  function Pop:TObject;
  function IsEmpty:Boolean;
  property Count:Integer read GetCount;
end;
Die Daten sind bei dir anscheinend nur Strings.
Ich würde empfehlen jeden Datensatz in einem Objekt zu speichern.

Die beiden Threads mit ihren Empfangs- und Sendequeue bilden jeweils einen Actor.

Klaus01 14. Jun 2013 12:27

AW: Zugriff mehrerer Threads aufeinander
 
..zu beachten ist dann noch wie zeitkritisch das ganze sein darf.
Also wenn Daten aus Typ1 ausgelesen werden, müssen die dann sofort in ein Typ2 Gerät geschrieben werden? Oder ist es relativ egal wann die Daten in den jeweilig anderen Typ geschrieben werden.

Grüße
Klaus

milchbrötchen 14. Jun 2013 12:38

AW: Zugriff mehrerer Threads aufeinander
 
Ok das mit dem Auslagern der Aufgabenliste aus den Threads find ich gar nicht so schlecht :)
(das waren jetzt beispielhaft nur Stringlisten, das sind eigentlich noch ein paar mehr Daten und Datentypen, es geht ja aber ums Prinzip)

Code:
  taufgabensorte1 = class(tthread)
    private
      // liste: tstringlist;
    ...

  taufgabensorte2 = class(tthread)
    private
      // liste: tstringlist;
    ...

  talleaufgaben = class
    private
      liste1: tstringlist;
      liste2: tstringlist;
      array1: array of taufgabensorte1;
      array2: array of taufgabensorte2;
    ...
Wie greife ich denn im obigen Beispiel aus den Threads in den beiden Arrays auf die beiden stringlisten liste1 und liste2 zu? :oops::oops:

(das ganze ist nicht so zeitkritisch)

Klaus01 14. Jun 2013 13:35

AW: Zugriff mehrerer Threads aufeinander
 
..
Delphi-Quellcode:
tabelleAufgaben = class
     function getNextTask(TypeId):TaskToDo;
Grüße
Klaus


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:22 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