![]() |
bei mehreren threads reagiert form1 nicht
Hi,
mein testprog soll mehrere threads gleichzeitig abarbeiten und dabei den zähler im memo ausgeben.. das funktioniert soweit auch - ABER sobald ich mehr als einen thread starte kann ich die form bis alle threads abgearbeitet sind nicht mehr bewegen... bei einem einzelnen thread funzt es aber ohne Probleme :gruebel: Danke für die Hilfe Ralf hier der code:
Delphi-Quellcode:
Tmythread = class(TThread)
tcount: integer; protected procedure execute; override; procedure display; end; var Form1: TForm1; mythr: array[0..5] of TMyThread; ithread: integer; implementation {$R *.dfm} procedure Tmythread.display; begin form1.Memo1.Lines.Add(inttostr(tcount)); end; procedure tmythread.Execute; begin tcount:=1; repeat synchronize(display); inc(tcount); until tcount>1000; end; procedure TForm1.Button1Click(Sender: TObject); begin for ithread:=0 to 5 do begin mythr[ithread]:= tmythread.create(true); mythr[ithread].FreeOnTerminate:=true; mythr[ithread].resume; end; end; |
Re: bei mehreren threads reagiert form1 nicht
Hi,
keiner eine Idee ? Ich komme hier nicht weiter .. die Form sollte sich doch eigntlich bei Verwendung von Threads und Synchronize(Display) jederzeit bewegen lassen oder habe ich hier einen Denkfehler ? Die Threads werden parallel abgearbeitet (was ich anhand der Zahlen im Memo sehen kann) aber der Hauptthread von Form1 scheint durch synchronize(Display) blockiert zu werden :gruebel: Danke Ralf |
Re: bei mehreren threads reagiert form1 nicht
Bei synchronize; wird ja der Hauptthread solange angehalten, bis die damit aufgerufene Funktion beendet ist ... ich vermute einfach mal, daß nun die "vielen" Threads einfach zuschnell den Hauptthread sperren, so das dieser keine Chance bekommt irgendwas abzuarbeiten.
Versuch mal Forlgendes:
Delphi-Quellcode:
und bei "echt" vielen Thread muß (wenn's klapt) die Zeit aber vergrößert werden, da sie sich ja im Durchschnitt aufteilt ... also bei 50 Threads bleiben (100 / 50 = 2) ja wiederum nur noch durschschnittlich 2 ms Zeit, in denen der Hauptthread was machen kann.
procedure tmythread.Execute;
begin tcount:=1; repeat synchronize(display); sleep(100); // ein bissl Zeit für'n Hauptthread inc(tcount); until tcount>300; end; |
Re: bei mehreren threads reagiert form1 nicht
Hi,
Deine Vermutung scheint zu stimmen - mit dem eingebauten sleep funktioniert es - obwohl ich dachte, dass bei der Verwendung von threads dieses Problem nicht auftaucht, da jeder auch der Hauptthread seinen Anteil an der Zeitscheibe erhält - die threads haben ja dieselbe Priorität - na ja wieder was dazugelernt... Danke Ralf |
Re: bei mehreren threads reagiert form1 nicht
Da du nur ganz einfach Integers weitergibst, warum verwendest du nicht PostMessage um den Integer ans Fenster zu schicken? Ist doch "sparsamer" und allemale bequemer als ständig mit Synchronize rumzuwerkeln.
PostMessage statt SendMessage, weil ersteres nicht blockt. |
Re: bei mehreren threads reagiert form1 nicht
Zitat:
Man könnte ja auch nu das INC selber locken und vom Haupthread (in 'ner Schleife auslesen)
Delphi-Quellcode:
procedure tmythread.Execute;
begin tcount:=1; repeat InterlockedInc(tcount); // ich glaub so hies das until tcount>1000; end; // entweder im Hauptthread // // oder in ähnlicher Weise in einem Nebenthread, // der als Einziger auf den Hauptthread zugreift While ... do Begin Label1.Caption := IntToStr(mythread.tcount); Application.ProgresMessages; Sleep(100); End; |
Re: bei mehreren threads reagiert form1 nicht
Die beste Variante (wie bereits gepostet) erscheint mir hier auch die Verwendung von PostMessage. Und das der Hauptthread nix mehr macht ist wirklich kein Wunder. Denn durch die vielen Threads und die Verwendung von Syncronize kommt der Hauptthread gar nicht mehr dazu was zu machen da ständig irgend ein Thread ein syncrones Arbeiten erzwingt. Da kann man die Threads auch gleich weg lassen. Oder eben PostMessage verwenden.
|
Re: bei mehreren threads reagiert form1 nicht
Eine andere "einfach" Lösung ist halt, statt dem Sleep (von oben) einfach etwas mehr Code einzufügen ... denn wenn zwischen den einzelnen aufrufen von SYNCHRONIZE genug Zeit vergeht, dann würde es ja dennoch "laufen"
Delphi-Quellcode:
procedure tmythread.Execute;
begin tcount:=1; repeat synchronize(display); ... // viel Rechenzeit until tcount>1000; end; procedure tmythread.Execute; begin tcount:=1; repeat //if display and $FF = 1 then synchronize(display); if display mod 256 = 1 then synchronize(display); // mit AND isses schneller ... // nich ganz so viel Rechenzeit until tcount>1000; end; // die 256/$FF sind nur als Beispiel und müßten entsprechend angepasst werden ;) |
Re: bei mehreren threads reagiert form1 nicht
die Frage ist ob das Syncronize notwendig ist wenn man nur einen Integer übermitteln will den man mit Syncronize übermitteln kann. Alternativ könnte man auch noch einen Timer einbauen und im Timer-Event die Werte der Threads abfragen und ins Memo packen.
|
Re: bei mehreren threads reagiert form1 nicht
Zitat:
Das mit dem Timer ist eigentlich mit am Besten, um einem User den Status mitzuteilen (denk ich) ... die Anzeige kommt schon regelmäßig, egal wie schnell der PC die Schleife abarbeitet (man braucht da also nichts mehr steuern/nachregeln) Hatte da mal soein Konstrukt.
Delphi-Quellcode:
Da isses halt Einfacher und Sparrsamer, wenn von außen angefragt wird :)
While ... do Begin;
... If GetTickCount - Timer > 1000 Then Begin Timer := GetTickCount; ... // Status ausgeben End; End; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:39 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-2025 by Thomas Breitkreuz