![]() |
arrays redefinieren während laufender Threads
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 |
Re: arrays redefinieren während laufender Threads
Zitat:
Du schreibst ja wahrscheinlich:
Delphi-Quellcode:
Und schon hast du ein Problem, da die Länge implizit in Registern gespeichert wird.
for i := Low(globalArray) to High(globalArray) do
..... globalArray[i] .....; |
Re: arrays redefinieren während laufender Threads
Zitat:
Grüße, Messie |
Re: arrays redefinieren während laufender Threads
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 |
Re: arrays redefinieren während laufender Threads
Zitat:
Oder du schaust dir mal die Klasse TThreadList an. |
Re: arrays redefinieren während laufender Threads
Zitat:
Ich habe mal ein kleines Beispiel gebaut, wie ich das abwickeln wollte. Lief jetzt eineinhalb Stunden ohne Probleme.
Delphi-Quellcode:
Ist das so tatsächlich nicht zulässig?
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); Grüße, Messie |
Re: arrays redefinieren während laufender Threads
Zitat:
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:
* der Thread wird gestartet (Resume) und berechnet z.B. Primzahlen in dem Array
type
TT = class(TThread) WorkArray : array of Integer; CurrentIndex : integer; procedure execute;override; end; * 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) |
Re: arrays redefinieren während laufender Threads
Zitat:
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz