AGB  ·  Datenschutz  ·  Impressum  







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

Array in Thread übergeben

Ein Thema von Osse · begonnen am 24. Mai 2005 · letzter Beitrag vom 8. Jun 2005
Antwort Antwort
Seite 1 von 2  1 2      
Osse

Registriert seit: 25. Mär 2005
Ort: Hamburg
74 Beiträge
 
Delphi 5 Enterprise
 
#1

Array in Thread übergeben

  Alt 24. Mai 2005, 23:33
HAllo,

zunächst ein kleiner Überblick, über mein Programm.

Ich habe drei Threads, die laufen.

Der erste guckt die ganze Zeit ob daten angekommen sind.
Der zweite kümmert sich um die Visualisierung.
Der dritte speichert die angekommenen Daten.

Die Daten in einem extra Thread zu speichern, ist sinnvoll da der Dateizugriff sehr lange Dauert (hab ich gelesen). Meine Anwendung muss allerdings sehr schnell sein, da ich jede ms ca. 150 Telegramme bekomme und diese auch dann speichern will in eine .csv Datei. Für diesen Zweck habe ich mir einen Ringspeicher angelegt in dem die Ankommenden Daten gespeichert werden.

Nun zu meinem Problem:

Da ich es nicht schaffe den array mit den Daten zwischen den zwei Threads zu synchronisieren, da ich zum einen einen statischen Array (Datenspeicher) angelegt habe (TRcvThread)und einen Zeiger übergebe.

Delphi-Quellcode:
 TRcvThread = class(TThread)
   private
      hClient: Byte;
      procedure DatenAusgeben;
      procedure Eingangsabgleich;
      procedure DatenSpeichern;
   protected
      procedure Execute; override;
   public
      Datenspeicher : array[0..Max_Anzahl_Datenspeicher] of TCANRcvMsg;
      Datenzaehler : Cardinal;
      procedure Set_hClient(_client : Byte);
      procedure GetDateiDaten(_Datenspeicher : array of TCANRcvMsg ; _Datenzaehler : cardinal);
   end;

 TDateiSchreiben = class(TThread)
   private
    Datei : TextFile;
    Datenzaehler : cardinal;
    Datenspeicher : array of TCANRcvMsg;
    procedure DatenFuerDateiHolen;
    procedure DatenSchreiben;
      { Private-Deklarationen }
   protected
      procedure Execute; override;

   public
      Dateiname : String;
   end;


procedure TRcvThread.GetDateiDaten(_Datenspeicher : array of TCANRcvMsg ; _Datenzaehler : cardinal);
begin
   _Datenzaehler := Datenzaehler;
   _Datenspeicher := Datenspeicher;
end;

procedure TDateiSchreiben.DatenFuerDateiHolen;
begin
  FRcvThread.GetDateiDaten(Datenspeicher , Datenzaehler);
end;
Darum hab ich ihn einfach global deklariert, so dass beide Threads drauf zugreifen können. Dies ist sehr unsauber, und am liebsten möchte ich den Datenarray synchronisieren. Da diese variante aber rel. lange dauert, bin ich auf die kritischen Abschnitte gestoßen. Leider werde ich aus dem cs Beispiel aus Luckies Toutorial nicht schlau, da die rede von einem "Zeiger auf eine RTL_CRITICAL_SECTION Struktur" ist. Ist das mein array?? wie muss ich den initalisieren??

Noch eine letzte Frage zu den Threads: Soll ich den Daten speichern Thread immer wieder beenden, wenn er fertig, oder erst am Programmende??
Das aufrufen benötigt doch auch zeit??

Vielen Dank und Gruß aus HH
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Array in Thread übergeben

  Alt 25. Mai 2005, 06:10
Die Lösung ist recht einfach, Du musst anstatt array of TCANRcvMsg zu direkt nutzen, einen Typ deklarieren und den nutzen.
Delphi-Quellcode:
type
  TCANRcvMsgArray = array of TCANRcvMsg;
...
  procedure GetDateiDaten(_Datenspeicher : TCANRcvMsgArray ; _Datenzaehler : cardinal);
...
  Datenspeicher : TCANRcvMsgArray;
...
......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#3

Re: Array in Thread übergeben

  Alt 25. Mai 2005, 09:30
Zitat von Osse:
da die rede von einem "Zeiger auf eine RTL_CRITICAL_SECTION Struktur" ist. Ist das mein array?? wie muss ich den initalisieren??
Die Struktur an sich ist offiziell undokumeniert. Daher nur ein Pointer.

Zitat von Osse:
Noch eine letzte Frage zu den Threads: Soll ich den Daten speichern Thread immer wieder beenden
Bloß nicht. Der Overhead wäre immens. Es würde reichen ihn einzuschläfern (suspend) und wieder aufzuwecken.
  Mit Zitat antworten Zitat
Osse

Registriert seit: 25. Mär 2005
Ort: Hamburg
74 Beiträge
 
Delphi 5 Enterprise
 
#4

Re: Array in Thread übergeben

  Alt 26. Mai 2005, 18:26
Danke sakura und Olli,

hab das Problem jetzt anders gelöst.

Zitat:
Die Lösung ist recht einfach, Du musst anstatt array of TCANRcvMsg zu direkt nutzen, einen Typ deklarieren und den nutzen

Hab einfach einen 2dim Array angelegt und übergebe immer in welchem ich arbeite.
Hatte bei sakura Lösung ein Problem mit meinen Threads beim beenden. War aber sonst super Idee .

Noch eine letzte Frage zu den Threads:

Zitat:
Es würde reichen ihn einzuschläfern (suspend) und wieder aufzuwecken.
Ich möchte den 2. thread über eine synchronisierung Starten. Kann ich einfach in der Routine den Thread wieder aufwecken??Wenn ja, wie ist die Syntax??

Delphi-Quellcode:
procedure TDateiSchreiben.Execute;
begin
   var
   dwResult: Longword;
   Zaehler : Integer;      // Zählvariable für die Datei
   Dateiname : String;
   Datei : TextFile;
begin
  try
    Synchronize(DatenEinlesen); // Datenspeicher + Zähler werden aus dem RcvThread eingelesen
    Dateiname := DateToStr(Date) + '.csv'; //Daetinamen erstellen, mit Hilfe des Datums
    AssignFile(Datei,Dateiname);       //Datei erstellen zum schreiben der Daten
    If FileExists(Dateiname)then //Prüfen ob Datei schon vorhanden ist. Wenn Ja, dann abfragen, ob datei überschrieben
      begin
   {$I-}
   Reset(Datei);
   Append(datei);
   {$I-}
      end
   else
     begin
   {$I+}
   ReWrite(datei); //Datei neu anlegen
   writeln(datei,    '" # "'   );
   writeln(datei,    '" ID "' ....+ ';' + '" Time micros"');
    for Zaehler := 1 to Max_Anzahl_Datenspeicher do
      writeln(datei, IntToStr(Datenspeicher[Speicherauswahl,Zaehler].msgbuff.ID)...);
   closefile(datei);
  except
    showmessage(' Es ist ein Fehler beim speichern der Daten aufgetreten!!! Dies könnte zum unerwünschten Datenverlust führen!!');
  end;
end;

Wo muss ich denn jetzt "suspend" einfügen und wie wecke ich den Thread wieder auf??

Danke
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#5

Re: Array in Thread übergeben

  Alt 26. Mai 2005, 21:03
Zitat von Osse:
Ich möchte den 2. thread über eine synchronisierung Starten. Kann ich einfach in der Routine den Thread wieder aufwecken??Wenn ja, wie ist die Syntax??
Also in dem Fall würde ich folgendes vorschlagen:
- Der (2.) Thread macht seinen Job und legt sich dann selber schlafen (vorher ggf. noch ein Event sigjnalisieren)
- Der Thread welcher den 2. Thread wecken soll wartet auf das Event (oder macht was anderes) und weckt den 2. Thread sobald wieder was anliegt.
  Mit Zitat antworten Zitat
Osse

Registriert seit: 25. Mär 2005
Ort: Hamburg
74 Beiträge
 
Delphi 5 Enterprise
 
#6

Re: Array in Thread übergeben

  Alt 27. Mai 2005, 00:30
Hey Olli

Zitat:
- Der (2.) Thread macht seinen Job und legt sich dann selber schlafen (vorher ggf. noch ein Event sigjnalisieren)
- Der Thread welcher den 2. Thread wecken soll wartet auf das Event (oder macht was anderes) und weckt den 2. Thread sobald wieder was anliegt.
Das hört sich so nicht schlecht an und dieser Gedankengang ist mir nicht fremd, aber "Ohne Arme keine Kekse".
Hast du zufällig ein wenig Quellcode für mich, Bitte Bitte Bitte, das wäre ganz

Danke
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Array in Thread übergeben

  Alt 27. Mai 2005, 11:49
Mir ist nochwas aufgefallen:

In Threads niemals direkt ein Showmessage direkt verwenden, weil das Modal ist und den Thread anhält - das geht mal und mal nicht und kann abartige Fehlermeldungen verursachen. Da mußt Du eine Routine mit synchronize verwenden und die Fehlermeldung einer globalen oder Form-Variable übergeben.

Zweitens ist es wichtig, daß Du beim Beenden des Programms oder des übergeordneten Threads die suspended Threads aufweckst und beendest (mit terminate und waitfor), sonst gibt das gelegentlich Stress beim Schließen. Vorher die Priorität des terminierten Thread mindestens auf tpnormal sezten.

Für die Synchronisation kannst Du auch Mutexe verwenden. Aber auch dabei ist die Einstellung der Threadpriorität wichtig.
Ich bin auch nicht sicher, ob die Benutzung des synchronize-Befehls zwischen Threads gefährlich ist.

Grüße, Messie
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Array in Thread übergeben

  Alt 27. Mai 2005, 11:51
Bei ShowMessages in einem Thread wird übrigens eine Exception der Art: "Canvas erlaubt kein Zeichen" geworfen. Mit einer Mesaagebox geht es allerdings.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
messie

Registriert seit: 2. Mär 2005
Ort: Göttingen
1.592 Beiträge
 
Delphi 2009 Professional
 
#9

Re: Array in Thread übergeben

  Alt 27. Mai 2005, 12:38
@ Michael:

was hältst Du von den synchronize-Befehlen zwischen den Threads?

Grüße
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Array in Thread übergeben

  Alt 27. Mai 2005, 12:42
Keine Ahnung, ob die Methode dazu gedacht oder geeigent ist. Ich würde es mit CriticalSections machen, da ich da weiß, was ich mache.
Michael
Ein Teil meines Codes würde euch verunsichern.
  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 08:46 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