Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Threadsynchronisation (https://www.delphipraxis.net/33837-threadsynchronisation.html)

StanY 13. Nov 2004 14:16


Threadsynchronisation
 
Ich habe ein Problem mit der Synchronisation bei meinen Threads.

Ich habe ein Socket (TIdTCPClient) und dazu einen Thread, welcher ReadLn aufruft:

Delphi-Quellcode:
procedure TMyThread.Execute();
var
  Msg: String;
begin
  while Connection[SockId].Connected = true do begin
    Msg := Connection[SockId].ReadLn;
    WriteLn(Msg);
  end;
end;
Nun habe ich beim Beenden das Problem, dass ich bei dieser Zeile:
Delphi-Quellcode:
WriteLn(Msg);
Einen Fehler bekomme, weil Connection[SockId] nicht 'connected' ist.

Lösen wollte ich das Problem so, dass ich beim Beenden folgendes Aufrufe:

Delphi-Quellcode:
  //erst die Threads beenden, damit keine Fehler auftreten
  for i := 0 to High(Connection) do begin
    Connection[i].Thread.Terminate;
  end;
und ein Stück code weiter:

Delphi-Quellcode:
  for i := 0 to High(Connection) do begin
    Connection[i].Disconnect;
    Connection[i].Free;
  end;
Allerdings bekomme ich denselben Fehler \:

Wer weiß Rat? (:

fiasko 13. Nov 2004 15:14

Re: Threadsynchronisation
 
Hallo,

du solltest vielleicht das Terminieren so machen:

Delphi-Quellcode:
Connection[i].Thread.Terminate;
Connection[i].Thread.WaitFor;
das Terminate beendet die Threads ja nicht sofort, waitfor wartet bis sie wirklich weg sind.

StanY 13. Nov 2004 15:24

Re: Threadsynchronisation
 
Das Problem daran ist, oder scheint folgendes zu sein:

Dadurch, dass der Thread erst beendet wird, wenn er zu Ende 'gelaufen' ist. Wartet er sich bei ReadLn; tot, da keine Nachrichten vom Server kommen (;.

fiasko 13. Nov 2004 16:32

Re: Threadsynchronisation
 
Jo, jetzt verstehe ich dein Problem auch langsam ;-). Dann mach also nach dem .Terminate das Disconnect und lass das WaitFor drinne. Vor dem WriteLn machst du noch eine Überprüfung rein ob immernoch Connected ist und dann müßte das gehen. Das ist aber nicht ganz sauber, da zwischen dieser überprüfung und dem WriteLn gerade das disconnect kommen könnte - eigentlich müßtest du das mit gegenseitigen Ausschluß schützen.

StanY 13. Nov 2004 16:59

Re: Threadsynchronisation
 
Will heißen? Ich würde es gerne sehr sauber lösen :D

fiasko 13. Nov 2004 17:30

Re: Threadsynchronisation
 
Ich stelle mir das so vor:

Delphi-Quellcode:
procedure TMyThread.Execute();
var
  Msg: String;
  c: boolean;
begin
  while not Terminated do
  begin
    EnterCriticalSection(..);
    if not Connection[SockId].Connected then break;

    Msg := Connection[SockId].ReadLn;
    WriteLn(Msg);
    LeaveCriticalSection(..);
  end;
end;
Delphi-Quellcode:
  //erst die Threads beenden, damit keine Fehler auftreten
  for i := 0 to High(Connection) do begin
    EnterCriticalSection(..);
    Connection[i].Disconnect;
    LeaveCriticalSection(..);
  end;
Also z.B. für den Thread (für jede Instanz!) eine TCriticalSection definieren.

StanY 15. Nov 2004 14:39

Re: Threadsynchronisation
 
Kurz und knapp: Versteh' ich nicht (;

Was meinst du mit 'EnterCriticalSection'?

(sry)

supermuckl 15. Nov 2004 17:11

Re: Threadsynchronisation
 
wie wärs mit try except ?

Luckie 15. Nov 2004 17:14

Re: Threadsynchronisation
 
Zitat:

Zitat von fiasko
Ich stelle mir das so vor:

Delphi-Quellcode:
procedure TMyThread.Execute();
var
  Msg: String;
  c: boolean;
begin
  while not Terminated do
  begin
    EnterCriticalSection(..);
    if not Connection[SockId].Connected then break;

    Msg := Connection[SockId].ReadLn;
    WriteLn(Msg);
    LeaveCriticalSection(..);
  end;
end;

Wenn du mit break aus der Schleife springst, wird nie LeaveCriticalSection aufgerufen und du hast ein DeadLock.

fiasko 15. Nov 2004 19:12

Re: Threadsynchronisation
 
Zitat:

Zitat von Luckie
Wenn du mit break aus der Schleife springst, wird nie LeaveCriticalSection aufgerufen und du hast ein DeadLock.

Huch :oops: da gehört natürlich zumindest noch ein try finally drumm - aber ganz ohne Exception Handling wollte das wohl hoffentlich eh keiner übernehmen :mrgreen:


Eine TCriticalSection ist eine Mutex Implementierung auf win32 Systemen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:47 Uhr.

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