Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Programm friert trotz Thread ein (waitforsingleobject) (https://www.delphipraxis.net/88529-programm-friert-trotz-thread-ein-waitforsingleobject.html)

TheMiller 16. Mär 2007 18:49


Programm friert trotz Thread ein (waitforsingleobject)
 
Hallo,

ich habe einen Thread, damit mein Hauptprogramm (Hauptthread) nicht einfriert. Jetzt muss ich allerdings auf die Beendigung der Prozedur aus dem Thread warten und nutze dazu "wairforsingleobject". Doch dabei friert mir ja wieder das Programm ein. Wie kann ich das unterbinden?

Danke im Voraus

Christian Seehase 16. Mär 2007 22:10

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
Moin DJ-SPM,

lass Dir doch von Deinem Thread eine Message (siehe, z.B., Hier im Forum suchenRegisterWindowMessage) schicken, wenn er fertig ist.

TheMiller 16. Mär 2007 23:05

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
Auf die Idee bin ich nicht gekommen. Aber ich habe eine Boolean-Variable gesetzt und im Hauptprogramm ein

Delphi-Quellcode:
while not (fertig) do
  Application.ProcessMessages
gesetzt. Ist das auch ok?

DGL-luke 16. Mär 2007 23:07

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
nicht, wenns nicht threadsicher ist (z.B. per Hier im Forum suchenCritical Sections)

negaH 17. Mär 2007 10:23

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
Zitat:

gesetzt. Ist das auch ok?
Ansich ja, nur das du damit den Vorteil des Threads global gesehen wieder zerstörst ;) Du hast ja den Thread gebaut damit effektiv gesehen keine unnötigen Prozessorresourcen, sprich CPU-Zeit, verschwendet wird, weil man auf igrendein Ereignis warten muß.

Dein Loop macht aber nun exakt dies. Sie pollt permanant und wartet das der Thread fertig wird. Sie vernichtet damit CPU-Zeit wweil sie die meiste Zeit nur while not fertig do; ausführt.

Ausgehend von diesem Source http://www.delphipraxis.net/internal...elay+revisited kann man das verbesseren.

Delphi-Quellcode:
function WaitFor(Event: THandle): Boolean;
begin
  Result := False;
  while not Result do
    case MsgWaitForMultipleObjects(1, Event, False, INFINITE, QS_ALLINPUT) of
      WAIT_OBJECT_0:
        Result := True;
      WAIT_OBJECT_0 +1:
        begin
          Application.ProcessMessages;
          if Application.Terminated then Exit;
        end;
    else
      RaiseLastWin32Error;
    end;
end;
Diese Funktion wartet auf ein Event, zb. Thread.Handle wird terminiert, und würde mit TRUE turückkehren. Solange dieses Event nicht eintritt wartet sie auf Nachrichten im Messagesqueue der Anwendung. Sind welche da so werden diese mit Application.ProcessMessages abgearbeitet. Sollte dabei die Anwendung beendet worden sein kehrt die Funktion mit FALSE zurück. Die restliche Zeit wo NICHTS passiert legt MsgWaitForMultipleObjects() den Mainthread der Anwendung Schlafen -> sowas wie Sleep(). Das führt dazu das diese CPU-Zeit dem Gesamtsystem zur Verfügung gestellt wird OHNE das deine eigene Rechnerzeit sinken würde.
Wenn zb. deine Mainthread und dein Arbeitsthreahd sich zu 50% die komplette CPU-Zeit teilen müssten soe würde nach deiner Methode die 50% des Mainthreades in einer sinnlosen Schleife verbraten. Der Arbeitsthread kann nur 50% der Rechnerzeit arbeiten. Mit obiger Variante würde der Mainthread aber wirklich nur arbeiten wenn 1. der Arbeitsthread fertig ist oder Messages vorliegen, also sagen wir mal 1% der 50% der Zeit. Die restliche Zeit kommt nun deinem Arbeitsthreah zugute. Dieser würde nun 99% der CPU Zeit bekommen und ergo doppelt so schnell fetig sein.

Obwohl man den Unterschied nicht wahrnimmt stellt WaitFor() die Bearbeitung im Program von einem Polling in ein Ereignisorientiertes System um. Dh. nur wenn ein Ereignis das wir wünschen eintritt werden wir aktiv. Beim Polling sind wir immer aktiv und fragen tausendemal einen Zustand ab der nur bveim 1001 mal tatsächlich eintrifft.

Gruß Hagen

PS: übrigens -> Thread.WaitFor; dürfte exakt das selbe machen ;)

Christian Seehase 17. Mär 2007 12:09

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
Moin Hagen,

Zitat:

Zitat von negaH
PS: übrigens -> Thread.WaitFor; dürfte exakt das selbe machen ;-)

tut es aber nicht.
Wenn Du TThread.WaitFor aufrufst, reagiert das Programm nicht mehr, bis WaitFor zurückkehrt.

TheMiller 17. Mär 2007 13:43

Re: Programm friert trotz Thread ein (waitforsingleobject)
 
@Christian Seehase: Das ist ja genau mein Problem gewesen. Diesen Thread habe ich ja nur erstellt, damit der MainThread nicht hängt. Der Thread braucht keine großartige Rechenleistung und dauer auch i.d.R nur 2-3 Sekunden. Deswegen habe ich mich für die fetig-Boolean-Variable entschieden...


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:26 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