Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - 2 Threads von gleicher Klasse -> Programm hängt


Passi077 - Fr 13.07.07 20:38
Titel: 2 Threads von gleicher Klasse -> Programm hängt
Hi,

kaum habe ich ein Problem gelöst, kommt das nächste..

Mein erster Thread läuft soweit nun :) .. wenn ich allerdings einen 2. erstelle und starte, so hängt sich das Programm sofort auf und freezt. Sieht also nach einem Deadlock aus, allerdings sehe ich nicht wo dieser erzeugt wird..

Hier mein Quelltext:
Die Thread-Klasse:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
unit Unit2;

interface

uses
  Classes, sysutils, StdCtrls, SyncObjs;

type
  TDLThread = class(TThread)
  private
    { Private-Deklarationen }
    count: integer;
    GUI: TLabel;
  protected
    procedure Execute; override;
    procedure DoSync;
  public
    constructor Create(pGUI: TLabel);
  end;

implementation

{ TDLThread }

constructor TDLThread.Create(pGUI: TLabel);
begin
  GUI := pGUI;
  FreeOnTerminate := True;
  inherited Create(False);
  Suspend();
end;

procedure TDLThread.Execute;
begin
  { Thread-Code hier einfügen }
 while not terminated do
 begin
  count := count + 1;
  Synchronize(DoSync);
 end;
end;

procedure TDLThread.DoSync();
begin
  GUI.caption := inttostr(count);
end;

end.




Und das Programm:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
var
  dlthreads : array of tdlthread;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  dlthreads[0].Resume();
//dlthreads[1].Resume();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  dlthreads[0].Suspend;
//dlthreads[1].Suspend;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  setlength(dlthreads, 2);
  dlthreads[0] := tdlthread.Create(label1);
  dlthreads[1] := tdlthread.Create(label2);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  dlthreads[0].Terminate();
//dlthreads[1].Terminate();
end;



Sobald ich den dlthreads[1] mit Resume starte, hängt sich das Programm sofort auf. Kann dann nur noch per STRG+F2 beenden werden.. lasse die Threads alle Suspended starten.

Ich hoffe, Ihr könnt mir helfen :)!

Grüße
Passi


Dunkel - Fr 13.07.07 21:17

Hallo!

Mach es lieber so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
constructor TDLThread.Create(pGUI: TLabel);
begin
  inherited Create(TRUE);  
  GUI := pGUI;
  FreeOnTerminate := True;
end;


Wenn Du den Thread mit TRUE createst dann ist dieser automatisch suspended. Siehe auch Delphi-OH!


Passi077 - Fr 13.07.07 21:42

Ah, ok Danke für den Tipp!

Leider ändert das noch nichts an dem Problem, dass sich das Programm aufhängt :(


Dunkel - Fr 13.07.07 21:58

user profile iconPassi077 hat folgendes geschrieben:
Ah, ok Danke für den Tipp!

Leider ändert das noch nichts an dem Problem, dass sich das Programm aufhängt :(

Ja, kann ich verifizieren.

Bei mir klappt es, wenn Du im Execute ein Sleep einbaust. In etwa so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TDLThread.Execute;
begin
  { Thread-Code hier einfügen }
 while not terminated do
 begin
  sleep(1);
  count := count + 1;
  Synchronize(DoSync);
 end;
end;

Frag mich aber nicht warum das so ist...


BenBE - Fr 13.07.07 22:47

Ist eigentlich ganz einfach ...

Beim Aufruf von Synchronize wird mit SendMessage eine Windows-Message an das Hauptfenster der TApplication (Application.Handle) gesendet. Wenn Du nun so häufig synchronisierst, dass die Hauptanwendung ständig nur noch Nachrichten behandelt, so kommt die Anwendung zu nix anderem mehr, da auch beim Bearbeiten anderer Nachrichten der Thread ja weiterhin Ereignisse produziert ...


Passi077 - Sa 14.07.07 00:10

Ah, ja, das klingt logisch :)

OK, dann wird sich das Problem automatisch beheben, sobald alles vollständig implementiert ist.

Danke für die Info!

Grüße
Passi