Announcement

Collapse
No announcement yet.

Benötige Hilfe bei Threads

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Benötige Hilfe bei Threads

    Hi,<p>
    über eine Schleife prüfe ich eine Vielzahl von Rechnern auf Verfügbarkeit. Da das etwas dauert, habe ich das Ganze in einen Thread ausgelagert, damit das Hauptprogramm bedienbar bleibt. Dazu habe ich die Idee von Andreas Kosch aus seinem Buch "Win32 Lösungen" aufgegriffen und initiiere am Anfang einen Thread, der sofort in den Suspend-Zustand übergeht.
    <pre>
    // Hauptprogramm
    mythread := TMyThread.Create;
    for i := 1 to RechnerAnzahl do
    begin
    ...
    mythread.Resume;
    repeat
    Sleep(0);
    until mythread.Suspended;
    ...
    end;
    *
    // Thread
    constructor TMyThread.Create;
    begin
    inherited Create(True);
    end;
    *
    procedure TMyThread.Execute;
    begin
    while not Terminated do
    begin
    ...
    Synchronize(WriteStatusbar);
    if Ping(FClient) <> -1 then
    ...
    Suspend;
    end;
    end;
    </pre>
    Mein Problem ist nun, dass die repeat-Schleife ewig durchlaufen wird. Scheinbar verabschiedet sich der Thread ins Nirwana ohne in den Suspend zu gehen. Was mache ich falsch?<p>
    Reimund

  • #2
    Hallo,

    &gt;Was mache ich falsch?

    warum wartet der primäre Thread überhaupt in einer repeat-Schleife? Wenn der zweite Thread vor dem eigenen Suspend-Aufruf über Synchronize eine Methode des primären Threads aufruft, wird doch auf diesem Weg das Ende des aktuellen Thread-Jobs gekennzeichnet

    Comment


    • #3
      Wow! Das ging aber schnell! Ich bin begeistert.<br>
      Diese Variante ist deutlich komplizierter als meine. Ich werde sie gleich mal bei mir einbauen und ausprobieren.<br>
      Vielen Dank einstweilen.<p>
      Grüße, Reimun

      Comment


      • #4
        Ups!<br>
        Jetzt ging wohl irgend etwas durcheinander. Gerade eben war noch ein Listing da...<p>
        Also, die Frage verstehe ich jetzt nicht ganz. Über Synchronize rufe ich TMyThread.WriteStatusbar auf, in dem in die Statusbar des Hauptformulars der aktuell bearbeitete Rechner geschrieben wird. Wird dadurch der 2. Thread automatisch beendet

        Comment


        • #5
          Hallo,

          &gt;Wird dadurch der 2. Thread automatisch beendet?

          die Situation lässt sich besser mit dem Wort "Deadlock" beschreiben. Die "Krücke" über Synchronize arbeitet nur dann, wenn der primäre Thread der VCL ungestört und pünktlich die eintreffende Windows-Botschaften abarbeiten kann. Im Normalfall ist das auch kein Problem, weil Borland dies tief in der VCL (TApplication-Methode <b>Idle</b>) automatisch macht. Wenn allerdings der primäre Thread der VCL durch eine eigene repeat-Schleife blockiert wird, kommt der Synchronize-Aufruf niemals dazu, seinen Job zu erledigen, der Thread kommt niemals dazu, die Methode Suspend aufzurufen und die repeat-Schleife im primären Thread wird niemals verlassen :-(

          Borland beschreibt dies im Papier "Changes to TThread in Delphi 6 and Kylix" so: "<i>TThread.Synchronize no longer uses a global window (ThreadWindow in D5's classes.pas) to coordinate with the main VCL thread. Instead, a TList, protected by a critical section, stores the events, and a new procedure in classes.pas, called CheckSynchronize, must be called at regular intervals to make Synchronize work. CheckSynchronize is a function which returns TRUE if at least one TThread had an event in the Synchronize queue when it was called.
          In a normal Delphi application, this work is performed by:<br>
          - For VCL applications: TApplication.Idle and TApplication.WndProc <br>
          - For CLX applications: TApplication.HandleMessage and TApplication.ProcessMessages<br>
          -For all applications: TThread.WaitFor<br>
          Most developers using Synchronize will not need to take any special action to make their code work with Delphi 6. Developers of a projects which do not use TApplication (such as ActiveX libraries), however, will need to call this manually or use something other than Synchronize.</i>". (Zitat Ende)

          P.S:

          &gt;..Gerade eben war noch ein Listing da.....

          Mein erster Entwurf der Antwort hat zwei Win32-Events und die Win32-API-Funktion MsgWaitForMultipleObjects verbaut, um beide Threads völlig sauber zu entkoppeln.

          Comment


          • #6
            Ich hab mal ein Application.ProcessMessages in die repeat-Schleife eingebaut und jetzt scheint es zu gehen. Reicht das tatsächlich oder ist es doch nur "Schein"

            Comment


            • #7
              Hallo,

              &gt;..Reicht das tatsächlich ...

              es ist nicht gerade sehr effizient, aber der Synchronize-Weg wird in diesem Fall nicht mehr verbaut, so dass das Deadlock-Problem verschwindet

              Comment


              • #8
                Ok, dann soll das für den ersten Step reichen. Leider drängt die Zeit. Wenn erst mal die erste Beta draussen ist, ist mehr Luft und dann werde ich noch mal das Listing mit den zwei Win32-Events studieren. Ist auf den ersten Blick zwar komplizierter als mein Weg, scheint dafür aber umso eleganter zu sein.<p>
                Vielen Dank für die Hilfe.<p>
                Grüße, Reimun

                Comment

                Working...
                X