AGB  ·  Datenschutz  ·  Impressum  







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

Mehrere Container für mehrere Threads?

Ein Thema von TheMiller · begonnen am 28. Feb 2008 · letzter Beitrag vom 28. Feb 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#1

Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:28
Hallo,

habe mich vor ein paar Tagen mit einigen aus dem Forum über Container und Threads unterhalten. Ich habe eine Containerklasse und ein Thread-Objekt erstellt. In der Containerklasse befindet sich ein Array, indem Daten vom Thread abgelegt und aufbereitet werden.

Das klappt alles wunderbar. Nur jetzt bekomme ich langsam das Problem, dass ich manchmal mehrere Threads gleichzeitig laufen habe, aber immer nur den gleichen Container. Ab un zu kommen Fehlermeldungen. Ich glaube, dass es Probleme gibt, wenn mehrere Threads auf das gleiche Array zugreifen und die Daten schnell nacheinander verändern. Denn das Hauptprogramm soll sich die Daten aus dem Array nehmen und anzeigen. Doch während es die Daten von Thread1 anzeigen möchte, hat Thread2 schon die Daten verändert und eine andere Struktur gespeichert. Nun kommt es zu AVs beim Anzeigen.

Nun ist die Frage, ob ich für jeden Thread einen eigenen Container erstellen soll und wann ich ihn dann freigeben soll? Nachteil wäre, dass ich wieder viele globale Container-Variablen habe, denn der Auftrag einen Thread zu erstellen und das Anzeigen der Daten sind in verschiedenen Methoden.

Ich hoffe, ihr versteht, was ich meine. Hier mal der Array-Code aus der Container-Klasse:

Delphi-Quellcode:
type
  TExpData = Array of String;
type
  TContainer=class(TSimpleRWSync)
  private
    FExpData: TExpData;

    function getExpData(i: Integer): String;
    function getExpDataCount: Integer;
  public
    procedure AddExpData(const Value: String);
    procedure ClearExpData;
    property ExpData[i: Integer]: String read getExpData;
    property ExpDataCount: Integer read getExpDataCount;
  end;

function TContainer.getExpData(i: Integer): String;
begin
  BeginRead;
  try
    result:=FExpData[i];
  finally
    EndRead;
  end;
end;

procedure TContainer.AddExpData(const Value: String);
begin
  BeginWrite;
  try
    SetLength(FExpData, Succ(Length(FExpData)));
    FExpData[High(FExpData)]:=Value;
  finally
    EndWrite;
  end;
end;

procedure TContainer.ClearExpData;
begin
  BeginWrite;
  try
    SetLength(FExpData, 0);
  finally
    EndWrite;
  end;
end;

function TContainer.getExpDataCount: Integer;
begin
  result:=High(FExpData);
end;
Danke im Voraus
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:43
GetExpDataCount solltest du auch in beginread und endread einbauen.

Wenn du nun gleichzeitig aus mehreren Threads Ergebnisse haben möchtest, dann musst du auch mehrere Container erstellen, oder in dem einen einen Container eine Logik entwickeln, dass du z.B. je ThreadID ein eigenes TExpData anlegst.

Aber global hast du doch hoffentlich die Container nicht. Du musst den Container im MainThread anlegen. Der Container selbst ist ein Feld vom Mainthread. Und dem Thread übergibst du nur (bspws.: im Constructor) den Container. also nicht als Kopie sondern nur dein Zeiger so wie er ist (einfache Zuweisung). Da kannst du auch verschiedene Container je Thread nehmen. Aber bitte nicht global.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:43
Dein Problem kannst du sehr einfach mit CriticalSections lösen.

Inplementiere eine TCriiticalSection als Feldvariable in deine Thread-Klasse.
Immer wenn auf gemeinsam genutzte Dateien, Objekte usw. zugegriffen wird, machts du das innerhalb einer CriticalSection.

Delphi-Quellcode:

...
FCriticalSection.Enter;
try
  //Zugriff auf gemeinsam genutzte Objekte, Dateien usw.
finally
  FCriticalSection.Leave;
end;
...
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:45
Zitat von Tyrael Y.:
Dein Problem kannst du sehr einfach mit CriticalSections lösen.
Das ist ja im Container bereits untergebracht
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#5

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:49
Hm...

mit der Erstellung des Containers habe ich es so gemacht:

Delphi-Quellcode:
var
  Form4: TForm4;
  Container: TContainer;

procedure TForm4.FormCreate(Sender: TObject);
begin
  Container:=TContainer.Create;
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  Container.Free
end;
Der Grund ist folgender: Die Prozedur StartThread startet den Thread und weist ihm den Container zu. Die Methode CallBack empfängt die Nachricht des Thread, dass er Daten in ExpData geschrieben hat und ruft dann eine entsprechende Prozedur auf, die die Daten anzeigt. Also habe ich zwei Prozeduren, die auf die Daten von "Container" zugreifen und daher Global als Variable von Form4 definiert. Ist das jetzt richtig oder falsch?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 15:57
Du musst eigentlich keine Variable global definieren. Lege sie doch als Feld in TForm4 hinein.

Startthread und Callback sehe ich nicht.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#7

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 16:03
Erklär mir das bitte nochmal genauer...

Hier nochmal die Methoden für's absenden des Threads und für's Empfangen der Nachrichten:

Delphi-Quellcode:
procedure TForm4.StartThread;
var
  SQL: TSQLThread;
begin
  SQL:=TSQLThread.Create(True);
  SQL.FreeOnTerminate:=True;
  SQL.postvars:=False;
  SQL.FHndl:=Form4.Handle;
  SQL.DataCode:=1; // Identifiziert LParam, damit ich mit case of arbeiten kann
  SQL.DataContainer:=Container;
  SQL.Resume;
end;

procedure TForm4.CallBack(var msg: TMessage);
begin
  if (msg.WParam = 1) then
  begin
    // LParam => Container.DataCode (also mein Identifizierungsmerkmal)
    case (msg.LParam) of
      1: Machwasmitdaten1;
      2: Machwasmitdaten2;
    end;
  end;
end;
Achso, und "Machwasmitdaten1" und "Machwasmitdaten2" machen GANZ unterschiedliche Dinge, greifen aber beide auf Container.ExpData[x] zu.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 16:13
Jo ist doch alles super programmiert.
Da brauchst du überhaupt keine globale Variable. Leg sie doch einfach in die Klasse TForm4 rein.

So und jetzt musst du dir halt überlegen, ob du für jeden Thread einen eigenen Container machst, oder in den einen Container mehrere TExpDatas.
Wann Freigeben? gute Frage:
1. Du schickst eine Message am Ende des SQL-Thread an den Mainthread, der den Container löschen soll
2. Du löschst den Container im onTerminate-Ereignis des Threads (geht nur, wenn du nicht in einer DLL bist; ist aber ansonsten mit Variante 1 gleichwertig)
3. Du nimmst Interfaces. Die Löschen sich selber, wenn sie nicht mehr benötigt werden (Das Interface musst du wahrscheinlich von IReadWriteSync ableiten)
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#9

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 16:16
Danke für das Kompliment - hast mir aber auch dabei recht viel geholfen!

Doch das verstehe ich immernoch nicht, wie meinst du das und wie kann ich dann mehrere Instanzen von "Container" haben

Zitat:
Da brauchst du überhaupt keine globale Variable. Leg sie doch einfach in die Klasse TForm4 rein.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Mehrere Container für mehrere Threads?

  Alt 28. Feb 2008, 16:25
Eine Sache sehe ich grade, lass mal das "Form4" vor dem ".Handle" weg.

Variablen gehören entweder als Feld in eine Klasse oder lokal in eine Methode:
Delphi-Quellcode:
type Txy=class(...)

     private
       FConatiner:Tcontainer; //Das ist ein Feld einer Klasse (deswegen so ein F davor)
     ...
     public
       //oder hier, dann kann man auch von außen drauf zugreifen, brauchst du aber nicht
end;

mehrere Instanzen:
Delphi-Quellcode:
type Txy=class(...)

     private
       FConatiner:array of Tcontainer; //Das ist ein Feld einer Klasse (deswegen so ein F davor)
     ...
     public
       //oder hier, dann kann man auch von außen drauf zugreifen, brauchst du aber nicht
end;
Wobei eine TObjectList anstatt des Arrays bedeutend besser wäre. Und jetzt kannst du für jeden Thread ein Element im Array füllen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:58 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