Einzelnen Beitrag anzeigen

Alex_ITA01

Registriert seit: 22. Sep 2003
1.115 Beiträge
 
Delphi 12 Athens
 
#3

AW: XE4 Probleme mit Thread.Start (anstatt Resume)

  Alt 26. Jun 2013, 08:21
So, habe es gelöst und meines Erachtens nach ein Fehler im TThread gefunden.

Delphi-Quellcode:
Constructor TMyThread.Create;
begin
  inherited Create(True);

  //hier noch paar Stringlisten oder ähnliches erstellen, welche im Execute vom Thread benutzt werden (deswegen mit Parameter True erstellt!)

  Start;
end;
Der Fehler entsteht folgender Maßen:

Das .Start im Constructor vom Thread nach dem Initialisieren von bestimmten Variablen ruft intern "InternalStart(False);" auf. Dies sieht wie folgt aus:

Delphi-Quellcode:
procedure TThread.InternalStart(Force: Boolean);
begin
  if (FCreateSuspended or Force) and not FFinished and not FExternalThread then
  begin
    FSuspended := False;
    FCreateSuspended := False;
{$IF Defined(MSWINDOWS)}
    if ResumeThread(FHandle) <> 1 then
      raise EThread.Create(SThreadStartError);
{$ELSEIF Defined(MACOS)}
    pthread_mutex_unlock(FCreateSuspendedMutex);
{$ELSEIF Defined(LINUX)}
    sem_post(FCreateSuspendSem);
{$ENDIF LINUX}
  end else
    raise EThread.Create(SThreadStartError);
end;
Damit wird FSuspended und FCreateSuspended zurückgesetzt (warum wird hier FCreateSuspended zurückgesetzt???).

Nach dem End; vom Constructor-Ende wird aber noch "AfterConstruction" aufgerufen.
Das sieht wie folgt aus:

Delphi-Quellcode:
procedure TThread.AfterConstruction;
begin
  if not FCreateSuspended and not FExternalThread then
    InternalStart(True);
end;
Damit wird InternalStart wieder aufgerufen mit Übergabe = True (Force). Da Force = True ist, kommt er in InternalStart auch wieder in das "ResumeThread <> 1" rein und macht sich ins Hemd, da der Thread ja bereits läuft (durch mein Aufruf von .Start).

Meines Erachtens nach dürfte doch das FCreateSuspended gar nicht zurückgesetzt werden. Die Variable soll doch dafür sein, um den Zustand zu erkennen, wie der Thread erstellt wurde! Wenn diese Variable nämlich nicht zurückgesetzt wird, würde es gehen, da "AfterConstruction" dann das "InternalStart(True)" nicht nochmal aufruft.

Bug? Absicht? Keine Ahnung.

Habe das ".Start" aus dem Constructor raus genommen und nach dem erstellen des Threads aufgerufen, dann gehts.

Hoffe damit auch den anderen suchenden geholfen zu haben.

Wenn hierzu jemand noch gerne was sagen möchte, würde ich mich freuen

Grüße
Alex
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat