Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Womit synchronisiert tThread.Synchronize? (https://www.delphipraxis.net/41119-womit-synchronisiert-tthread-synchronize.html)

xineohp 26. Feb 2005 12:56


Womit synchronisiert tThread.Synchronize?
 
moin,

Ich habe einen Thread, der eine einen anderen Thread startet. Der zweite Thread hat ein Ereignis, das eine Methode des ersten Threads aufruft. Meines Wissens nach muss ich das irgendwie synchronisieren ... Das (für mich) nächstliegende wäre die Funktion synchronize zu verwenden. Dabei bin ich mir jetzt aber nicht ganz sicher mit was/wem dann synchronisiert wird. Mein Ziel ist ja die Synchronisation mit dem ersten Thread, ich befürchte aber das die genannte Funktion mit dem Mainthread synchronisiert. Meine Frage ist nun wie ich das Ganze jetzt am Besten umsetze.

Luckie 26. Feb 2005 13:06

Re: Womit synchronisiert tThread.Synchronize?
 
Ich würde mit CriticalSections arbeiten. Delphi stellt da schon die Klasse TCriticalSection für bereit.

xineohp 26. Feb 2005 13:13

Re: Womit synchronisiert tThread.Synchronize?
 
hm, OK, werd ich tun.

Nur damit der Thread zum Titel passt :wink:: womit synchronisiert den nun synchronize?

HERMES 26. Feb 2005 13:13

Re: Womit synchronisiert tThread.Synchronize?
 
tach,

mit dem was du für synchronize vermutet hast, hast du recht. Wenn du eine Methode "syncronized" aufrufst wird diese im Hauptkontext der Anwendung ausgeführt, dies wird oft beim zugriff auf das GUI benutzt .
Also must du es machen wie Lukie gesagt hat, wenn eine synchronisierung überhaupt nötig ist!
Es ist nicht immer nötig Thraeads zu synchronisieren. Es ist nur nötig wenn man auf gemeinsame Daten schreibend zugreift, oder der eine Threads von ergebnissen des andern abhängig ist ( es gibt natürlich noch mehr gründe).

xineohp 26. Feb 2005 13:22

Re: Womit synchronisiert tThread.Synchronize?
 
@Hermes: thx

Ich bin mir beim Synchronisieren nie so ganz sicher was ich wie machen muss:

Zur Situation:
Ich habe einen Thread der Berechnungen durchführen soll, die er über eine Methoden vom übergeordneten Thread erhält, in einer Queue speichert und dann nach einander abarbeitet. Immer wenn er eine Berechnung beendet hat soll er dann ein Ereignis auslösen, damit der übergeordnete Thread sich das Ergebnis abholen kann.

Wie muss ich da jetzt was synchronisieren?

Luckie 26. Feb 2005 13:36

Re: Womit synchronisiert tThread.Synchronize?
 
Du löst einfach einen Event aus nach jeder Berechnung. Der übergeordnete Thread wartet auf diesen Event in einer Endlosschleife und verarbeitet jeweils das Ergebnis und diesen Zugriff auf die gemiensame Datenstruktur sollte man mit einer CriticalSection schützen.. Wenn die letzte Berechnung ausgeführt wurde, löst der Working Thread ein weiteres Ereiegnis aus und signalisiert dem übergeordnetetn Thread, dass er fertig ist, daraufhin verläßt der übergeordnete Thread die Endlosschleife und fertig.

Man kann auch auf das zweite Ereigniss verzichten, wenn dem übergeordneten Thread bekannt ist, wie viele Berechnungen durch zu führen sind.

xineohp 26. Feb 2005 13:54

Re: Womit synchronisiert tThread.Synchronize?
 
Ok, soweit so klar, du meinst also, ich sollte auf ein Ereignis verzichten und stattdessen einen Event verwenden.
Wie mache ich das aber, wenn ich mehrere Working-Threads habe? woher weiß ich wer jetzt gerade fertig ist?

EDIT: Um das Problem noch etwas zu verdeutlichen: Es handelt sich um eine Art Queue-Thread, der jeder Zeit neue Aufträge übernehmen können soll, die er dann in einer Liste speichern und an eine bestimmte Zahl von Working-Threads verteilen soll.

Luckie 26. Feb 2005 14:09

Re: Womit synchronisiert tThread.Synchronize?
 
Ich habe mir schon fast gedacht, dass du da noch mal nachfragst. Mach mal eine neue Konsolenanwendung und dann kopierst du das mal da rein:
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  Windows;

var
  hEvents: array[0..2] of THandle;

function WorkingThread(p: Pointer): Integer;
var
  i: Integer;
begin
  for i := 0 to 9 do
  begin
    writeln(i);
    sleep(1500);
    SetEvent(hEvents[0]);
  end;
  SetEvent(hEvents[1]);
  result := 0;
end;

function WatchThread(p: Pointer): Integer;
var
  bRunning: Boolean;
  ThreadID: Cardinal;
  wfmo: DWORD;
begin
  bRunning := True;
  CloseHandle(BeginThread(nil, 0, @WorkingThread, nil, 0, ThreadID));
  while bRunning do
  begin
    wfmo := WaitForMultipleObjects(length(hEvents)-1, @hEvents[0], False, INFINITE);
    if (wfmo - WAIT_OBJECT_0) = 0 then
    begin
      writeln('OK');
      SetEvent(hEvents[2]);
    end
    else
    begin
      writeln('Finish');
      bRunning := False;
    end;
  end;
  result := 0;
end;

var
  ThreadID: Cardinal;
begin
  hEvents[0] := CreateEvent(nil, False, False, 'Work');
  hEvents[1] := CreateEvent(nil, False, False, 'Finish');
  hEvents[2] := CreateEvent(nil, False, False, 'Continue');
  CloseHandle(BeginThread(nil, 0, @WatchThread, nil, 0, ThreadID));
  Readln;
end.
Nach jeder Ausgabe vom WorkingThread schreibt der WatchThread sein OK und zum Schluss, wenn der WorkingThread fertig ist eben "Finish". Das sleep ist nur dazu da, damit man sieht, wie das abläuft.

So das ganze ist etwas komplex. Mal sehen, ob ich es verständlich erklären kann. Im Prinzip benachrichtigen sich die Threads gegeseitig. Der WorkingThread sagt mit SetEvent(hEvents[0]);, dass eine Berechnung fertig ist. Der WatchThread wartet mit wfmo := WaitForMultipleObjects(length(hEvents)-1, @hEvents[0], False, INFINITE); auf die Signalisierung eines Events aus dem Array. Ist es das nullte Event, schreibt es sein OK in die Konsole. Dann löst es selber ein Event aus auf das der WorkingThread mit WaitForSingleObject(hEvents[2], INFINITE); wartet damit er weiter machen kann.

Im Endeffekt ist es auch eine CriticalSection - nur eben mit Benachrichtigung.

xineohp 26. Feb 2005 14:59

Re: Womit synchronisiert tThread.Synchronize?
 
wobei es in deinem Beispiel nur einen Working-Thread gibt. Wenn ich mit mehreren Working-Threads arbeiten will bräuchte ich doch für jeden Thread ein eigenes Event, oder? Das wiederum scheint mir nicht besonders elegant. Sollte ich nicht vielleicht doch ein Ereignis verwenden, das dann einen (Ab-)Sender mit bringt?

Luckie 26. Feb 2005 15:00

Re: Womit synchronisiert tThread.Synchronize?
 
Wir arbeiten doch schon mit Ereignissen: Event = Ereignis.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 Uhr.
Seite 1 von 2  1 2      

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