AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi arrays redefinieren während laufender Threads
Thema durchsuchen
Ansicht
Themen-Optionen

arrays redefinieren während laufender Threads

Ein Thema von messie · begonnen am 14. Sep 2005 · letzter Beitrag vom 14. Sep 2005
Antwort Antwort
messie

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

arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 10:34
Hallo,

in meiner Anwendung laufen verschiedene Threads, die -über Mutexe synchronisiert - auf verschiedene Rohdatenarrays zugreifen.
Nun muß ich zur Laufzeit die Länge verschiedener (globaler) arrays ändern.

Reicht es, daß ich die arrays zum Redefinieren mit den Mutexen verriegele oder werden die Informationen über die Arraylänge auch von den Threads gespeichert? Das könnte ja dazu führen, daß ein Thread auf einen Speicherbereich zugreift, der schon freigegeben ist.

Grüße, Messie
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 11:10
Zitat von messie:
... oder werden die Informationen über die Arraylänge auch von den Threads gespeichert?
So ist es.
Du schreibst ja wahrscheinlich:
Delphi-Quellcode:
for i := Low(globalArray) to High(globalArray) do
   ..... globalArray[i] .....;
Und schon hast du ein Problem, da die Länge implizit in Registern gespeichert wird.
Andreas
  Mit Zitat antworten Zitat
messie

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

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 11:28
Zitat von shmia:
Und schon hast du ein Problem, da die Länge implizit in Registern gespeichert wird.
Dann muß es ja eine Möglichkeit geben, die Threads über eine Veränderung zu benachrichtigen, sonst wäre eine Verwendung von offenen arrays mit Multithreading gar nicht möglich, oder?

Grüße, Messie
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 11:31
Hi Messie,

wenn du die Verriegelungszeit minimieren willst bzw. musst, dann kannst du ja bei entsprechenden Randbedingungen eine Copy(globalArray) ziehen.

Grüße vom marabu
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 11:31
Zitat von messie:
Dann muß es ja eine Möglichkeit geben, die Threads über eine Veränderung zu benachrichtigen, sonst wäre eine Verwendung von offenen arrays mit Multithreading gar nicht möglich, oder?
Du darfst die offenen Arrays nach Start der Threads nicht mehr resizen.
Oder du schaust dir mal die Klasse TThreadList an.
Andreas
  Mit Zitat antworten Zitat
messie

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

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 13:54
Zitat von shmia:
Du darfst die offenen Arrays nach Start der Threads nicht mehr resizen.
Das würde mich aber hart treffen.
Ich habe mal ein kleines Beispiel gebaut, wie ich das abwickeln wollte. Lief jetzt eineinhalb Stunden ohne Probleme.
Delphi-Quellcode:
type
  TT = class(TThread)
    procedure execute;override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Timer1: TTimer;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    procedure writedisplay;
    procedure initarray;
  end;

var
  Form1: TForm1;
  array1 : array of integer;
  Mutex : THandle;
  T : TT;

implementation

{$R *.dfm}

procedure TT.execute;
begin
  priority := tplower;
  application.ProcessMessages;
  while not terminated do
  begin
    try
    if WaitForSingleObject(Mutex,INFINITE) = WAIT_OBJECT_0 then
      synchronize(Form1.writedisplay);
    finally
      ReleaseMutex(Mutex);
    end;
    sleep(100);
  end;
end;

procedure TForm1.initarray;
var
  i : integer;
begin
  randomize;
  setlength(array1,0);
  setlength(array1,random(100000));
  Label1.Caption := IntToStr(high(array1)+1);
  for i := 0 to high(array1) do
  begin
    array1[i] := random(100);
  end;
end;

procedure TForm1.writedisplay;
var
  i : integer;
begin
  Memo1.Clear;
  for i := 0 to high(array1) do
  begin
    Memo1.Lines.Add(IntToStr(array1[i]));
    //application.ProcessMessages;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  initarray;
  if timer1.Enabled then
  begin
    timer1.Enabled := false;
    T.Terminate;
  end
  else
  begin
    timer1.Enabled := true;
    T := TT.Create(false);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  try
    if WaitForSingleObject(Mutex,INFINITE) = WAIT_OBJECT_0 then
    begin
      initarray;
    end;
  finally
    ReleaseMutex(Mutex);
  end;
end;

initialization
  Mutex := CreateMutex(nil,false,nil);

finalization
  Mutex := CreateMutex(nil,false,nil);
Ist das so tatsächlich nicht zulässig?

Grüße, Messie
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#7

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 14:57
Zitat von messie:
Ich habe mal ein kleines Beispiel gebaut, wie ich das abwickeln wollte. Lief jetzt eineinhalb Stunden ohne Probleme.
Delphi-Quellcode:
procedure TT.execute;
begin
  application.ProcessMessages; // das würde ich besser weglassen !!
  while not terminated do
  begin
   ...
      synchronize(Form1.writedisplay);
end;

procedure TForm1.writedisplay;
var
  i : integer;
begin
  Memo1.Clear;
  for i := 0 to high(array1) do
  begin
    Memo1.Lines.Add(IntToStr(array1[i]));
    //application.ProcessMessages;
  end;
end;
Ist das so tatsächlich nicht zulässig?
Das du [TThread.]Synchronize verwendest, und in writedisplay sämtlichen Arbeit mit dem dyn. Array abwickelst, passiert nichts.
writedisplay wird im Hauptthread abgearbeitet und unterbricht somit auch die Windows-Message-Loop für die Dauer der Ausführung.

Dadurch, dass die gesamte Arbeit mit dem Array im Hauptthread durchgeführt wird,
werden die Threads eigentlich sinnlos, da sie keine Arbeit verrichten.

Du solltest vielleicht eher so vorgehen:
* eine neuer Thread wird erzeugt (im Suspended-Status)
* im Hauptthread wird ein Array bestimmter Grösse dynamisch mit SetLength angelegt.
Delphi-Quellcode:
type
  TT = class(TThread)
    WorkArray : array of Integer;
    CurrentIndex : integer;
    procedure execute;override;
  end;
* der Thread wird gestartet (Resume) und berechnet z.B. Primzahlen in dem Array
* das Event OnTerminate wird benutzt, beim Threadende die Werte aus Workarray abzugreifen und auf ein Memofeld zu kopieren
* der Thread ist zu Ende und sollte entweder mit Free freigegeben werden oder FreeOnTerminate ist True

weitere Verbesserung:
Angenommen, du willst die Primzahlen von 1 bis 100000 errechnen.
Dann könnte der Thread alle 1000 Zahlen mit Synchronize eine Methode im Hauptthread aufrufen.
Damit kann der Hauptthread ermitteln, wie weit die Berechnung schon gediehen ist und dies anzeigen. (threadobj.CurrentIndex abfragen)
Andreas
  Mit Zitat antworten Zitat
messie

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

Re: arrays redefinieren während laufender Threads

  Alt 14. Sep 2005, 15:22
Zitat von shmia:
Du solltest vielleicht eher so vorgehen:
Mein Problem ist, daß ich die Änderungen in einer bestehenden Anwendung vornehmen muß. Deshalb muß ich etwas finden, was zur vorhandenen Struktur paßt.
Das mit dem synchronize ist richt, ist auch in meiner Anwendung nicht so (da gehört das array dem Hauptthread und wird auch dort verwaltetet und beschrieben, die einzelnen Threads kopieren nur gelegentlich Daten raus). Ich lasse die prozedur writedisplay jetzt innerhalb des Threads ohne synchronize ausführen (mit with Form1...). Ist nicht mehr so flüssig, funzt aber auch. Durch das infinite des Mutex hat sich natürlich gleich alles komplett verriegelt, was vorher nicht passieren konnte. Aber mit einer Totzeit geht es jetzt.

Grüße, Messie
  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 20:26 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