TThread terminate in FormClose (gelöst)

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

Re: TThread terminate in FormClose (gelöst)

Beitrag von wolf_z »

Hmm. Und einen vernünftigen integrierten Debugger hat MSE auch? Nicht wie dieser gdb, der keine Pascal-Typen kennt und auch keine bedingten Breakpoints kann (jedenfalls nicht bei mir) und der auch nicht unter Mac richtig läuft (jedenfalls nicht unter SnowLeopard)?

Apropos. Warum läuft MSE eigentlich nur unter Windows und Linux? Wenn Linux geht, müsste doch eigentlich auch Macintosh funktionieren?

Nachtrag: Hab mir gerade mal MSE auf Windows installiert. Sehr interessant. Werde mich damit mal etwas näher beschäftigen. Im Moment interessiert mich sowieso das Thema: "Wie weit komme ich mit welchen Pascal-Tools auf den verschiedenen Plattformen". Zumindest langfristig. Aktuell will ich alte Delphi-Applikationen auf Linux und Mac portieren. Delphi ist natürlich sehr VCL-bezogen. Deshalb ist eine Portierung auf Lazarus zunächst wohl einfacher. Aber bei dem Ärger, den man mit den Widgetsets hat, ist natürlich die Frage, ob man nicht gleich auf eine Lösung, wie MSE umsteigt. Allerdings ist dort die GUI etwas gewöhnungsbedürftig. Mal schaun.

Für MSE gibt es hier im Forum ja einen eigenen Bereich. Da kann ich dann ja näheres nachfragen. Danke jedenfalls für den tip!

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: TThread terminate in FormClose (gelöst)

Beitrag von mse »

wolf_z hat geschrieben:Hmm. Und einen vernünftigen integrierten Debugger hat MSE auch?
MSEide benutzt ebenfalls gdb. Möglicherweise ist das Interface etwas ausgereifter, jedenfalls ermöglicht mir der MSEide debugger, auch komplizierte und versteckte Fehler in kürzester Zeit zu reparieren, falls sie reproduzierbar sind. Zum Beispiel heute auf public.mseide-msegui.talk:
http://msegui.org/fudforum/index.php?t= ... 9d44ae6335

Bug gemeldet 5:56, reproduziert 9:22, repariert um 9:41.
Apropos. Warum läuft MSE eigentlich nur unter Windows und Linux? Wenn Linux geht, müsste doch eigentlich auch Macintosh funktionieren?
Ich selbst habe keinen Bedarf und bis jetzt hat sich kein Sponsor gemeldet. Auch ist das FPC ObjC Sprachinterface noch nicht fertiggestellt.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: TThread terminate in FormClose (gelöst)

Beitrag von mse »

wolf_z hat geschrieben: waitFor geht nicht mit 'onTerminate' zusammen!
Dann könnte das Problem hier liegen:

Code: Alles auswählen

procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then
    Synchronize(@CallOnTerminate);   <<<<<<<<--------
end;

Code: Alles auswählen

class procedure TThread.Synchronize(AThread: TThread; AMethod: TThreadMethod);
  var
    LocalSyncException: Exception;
  begin
    { do we really need a synchronized call? }
    if GetCurrentThreadID=MainThreadID then
      AMethod()
    else
      begin
        System.EnterCriticalSection(SynchronizeCritSect);    <<<<<<-------
        SynchronizeException:=nil;
        SynchronizeMethod:=AMethod;
 
        { be careful, after this assignment Method could be already executed }
        DoSynchronizeMethod:=true;
 
        RtlEventSetEvent(SynchronizeTimeoutEvent);
 
        if assigned(WakeMainThread) then
          WakeMainThread(AThread);
 
        { wait infinitely }
        RtlEventWaitFor(ExecuteEvent);                 <<<<<----
        LocalSyncException:=SynchronizeException;
        System.LeaveCriticalSection(SynchronizeCritSect);
        if assigned(LocalSyncException) then
          raise LocalSyncException;
      end;
  end;
Ein deadlock, falls checksynchronize() nicht solange aufgerufen wird, bis der beendete thread seine synchronize() Anforderung erhält.

wolf_z
Beiträge: 88
Registriert: Mo 31. Aug 2009, 09:31

Re: TThread terminate in FormClose (gelöst)

Beitrag von wolf_z »

mse hat geschrieben: MSEide benutzt ebenfalls gdb. Möglicherweise ist das Interface etwas ausgereifter, ...
Stimmt! Das ist mir direkt aufgefallen beim ersten Ausprobieren! :) Wirklich sehr interessant, Deine IDE. Vor allem auch die unglaubliche Leistung, die dahintersteckt, sowas zu entwicklen. Ich werde mich vielleicht mal demnächst etwas einarbeiten. Ich glaube, ideal ist MSE für Anwendungen mit Datenbank und grafischer Ausgabe und natürlich für datenbankgestützte Formularsysteme.

Allerdings ist für mich vor allem auch die Macintosh-Welt interessant, um den Markt für eigene Software zu verbreitern (die Mac-User haben Geld und lassen für ein Programm auch gerne mal ein paar Euro springen :mrgreen: ). Außerdem finde ich es strategisch wichtig für ein Entwicklungssystem, dass man auch etwas für die Mobile-Welt anbietet. Z.B. Maemo/Nokia wäre da zumindest für Lazarus interessant, weil es direkt auf gtk2 aufsetzt. Aber wie ich irgendwo gelesen habe, sind die von FPC generierten Binaries noch viel zu groß für Handys gegegenüber C++ oder ähnlichem. Das könnte ein Nachteil für alle Entwicklungssysteme sein, die auf FPC setzen. Auf der anderen Seite werden die Massenspeicher für Mobile-Gadgets ja auch immer größer. Wenn man auch etwas für iPhone anbieten könnte, wäre das natürlich genial. Da hab ich im Netz noch nichts brauchbares zu gefunden (außer den Apple-eigenen Tools und die sind eine Welt für sich). Außerdem: Google-Chrome, Android, ... Ist doch alles Linux. Eigentlich ideal für den Cross-Compiling Ansatz von Lazarus oder vielleicht auch MSE?

Aber was mir bei MSE noch aufgefallen ist: Es gibt gar keine Komponenten für das Internet. Vor allem ein Browser fehlt. Das hab ich bei qt direkt als erstes getestet, ob das möglich ist (weil ich bei einem meiner Programme sowas benötige). Für das meiste kann man ja das 'Synapse''-Framework nutzen. Aber daraus einen in die eigene Anwendung integrierten Browser zu stricken ist doch etwas mühsam. QT verwendet ja dafür den Safari. Der läuft auf allen Plattformen. Daraus könnte man dann auch schön eine Html-Hilfe aufsetzen. Denn das hab ich schon gemerkt. Wenn man auf chm setzt, gibt's jede Menge Inkompatibilitäten zwischen den Plattformen. Auch mit dem kchmviewer (oder so ähnlich heißt der). Für ein gutes Cross-Hilfesystem wäre somit eine Browserkomponente, die auf allen Betriebssystem gleich gut läuft, z.B. auf Safari-Basis, sehr interessant.

So! Jetzt nochmal zu meinem Beispiel. Ich hab in dem Code-Beispiel oben letzte Version immer noch Unsinn drin. Das kann ich so nicht stehen lassen. Critical Sections machen ja nur Sinn, wenn die Threads auf gemeinsame Ressourcen des Container-Objekts zugreifen. Deshalb hab ich das Beispiel nochmal überarbeitet. Hier die 'execute' der Threads

Code: Alles auswählen

procedure TLifeThread._status;
begin
  if assigned(FWorld.FonStatus) then
     FWorld.FonStatus(self, FStatus);
end;
 
procedure TLifeThread.Execute;
var starved:boolean; actLifeIndex:integer;
begin
  starved := false;
  while not Terminated do
     begin
     if basiceventWaitFor(1, _killEvent) = wrSignaled then
        begin
        basiceventResetEvent(_killEvent);
        FreeOnTerminate := false;
        terminate;
        break;
        end
     else
     if basiceventWaitFor(1, _fireEvent) = wrSignaled then
        begin
        basiceventResetEvent(_fireEvent);
        // add value to common resources
        EnterCriticalSection(GlobalLock);
        with FWorld do
           FResources := FResources + Value;
        LeaveCriticalSection(GlobalLock);
        Value := 0;
        // send status to GUI:
        FStatus := FName + ': reset to zero!';
        synchronize(@_status);
        end
     else
        begin
        Value := Value + 1;
        // receive one unit from common resources
        EnterCriticalSection(GlobalLock);
        with FWorld do
           FResources := FResources -1;
        LeaveCriticalSection(GlobalLock);
        // if all resources are wasted life starves
        if (FWorld.FResources = 0) and not FWorld.FdontStarve then
           begin                           // FdontStarve:=true on ...
           starved := true;                // ... World.terminateAllLifes
           with FWorld do
              begin
              EnterCriticalSection(GlobalLock);
              FResources := FResources + Value; // give back collected resources
              LeaveCriticalSection(GlobalLock);
              //    actLifeIndex := getThreadIndex(self); 
              FList.remove(self);
              end;
           end;
        // terminate live if starved
        if starved then
           begin
           freeOnTerminate := true;
           terminate;
           break;
           end;
        end;
 
     sleep(998);
     end;
end;
Im Rest des Programms hat sich natürlich auch noch was geändert. Deshalb den kompletten Source-Code nochmal im Anhang. Wer jetzt Lust hat, die "Grenzen des Wachstums" zu simulieren, der kann das mit dem kleinen Progrämmchen tun (z.B.: Wie wirken sich wenige Reiche und viele Arme auf die Weltressourcen aus?). Ansonsten weiß ich jetzt auch nicht mehr, was man an dem Programm noch alles verbessern könnte. Ich meine jedenfalls, jetzt Threads mit Lazarus ein bisschen besser verstanden zu haben. Vielen Dank nochmal für die Diskussion.

Grüsse Wolfgang

Nachtrag: Habe Datei nach Korrektur nochmal hochgeladen :oops: Sorry, ich hoffe, jetzt läufts wirklich! (21.11.09)
Dateianhänge
world.zip
Cross Beispiel parallele Threads
(110.44 KiB) 71-mal heruntergeladen

Antworten