| Autor |
Beitrag |
David
      
Beiträge: 27
|
Verfasst: Mo 09.02.04 18:50
Hallo,
ich habe ein kleines Probem. Ich versuche mich grad in Threads einzuarbeiten und leider stürzt mein Mini Programm immer ab.
Hier der Code:
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:
| var ThreadID : THandle; ThreadH : THandle; ThreadID2 : THandle; ThreadH2 : THandle;
procedure threadtest (Edit : TEdit); stdcall; var a: integer; begin for a:=0 to 5000 do ShowMessage('Thread 1 fertig!'); ThreadH:=0; end;
procedure threadtest2 (Edit : TEdit); stdcall; var a: integer; begin for a:=0 to 1000 do ShowMessage('Thread 2 fertig!'); ThreadH2:=0; end;
procedure TForm1.Button1Click(Sender: TObject); begin ThreadH:=CreateThread(nil,0,@threadtest,Edit1,0,ThreadID); ThreadH2:=CreateThread(nil,0,@threadtest2,Edit1,0,ThreadID2); end; |
Mit einem Thread geht es, aber bei 2 kann ich es vergessen.
Jemand ne Ahnung was ich falsch gemacht habe?
Moderiert von Peter Lustig: Code- durch Delphi-Tags ersetzt
|
|
patrick
      
Beiträge: 1481
WIN2k, WIN XP
D6 Personal, D2005 PE
|
Verfasst: Mo 09.02.04 19:02
irgendwie erstelle ich theads ganz anders
schau dir am besten mal das thread-tut von Luckie an:
www.luckie-online.de...threads_tutorial.pdf
so mach ich das immer:
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:
| unit thread_unti1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls;
type TmyTThread = class(TThread) public procedure Execute; override; end;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public
end;
var myt1,myt2:TmyTThread; implementation
{$R *.dfm}
procedure TmyTThread.Execute; var i:integer; begin end;
procedure TForm1.Button1Click(Sender: TObject); begin myt1.Create(false); myt2.Create(false); end;
end. |
_________________ Patrick
im zweifelsfall immer das richtige tun!!!
Zuletzt bearbeitet von patrick am Mo 09.02.04 19:08, insgesamt 1-mal bearbeitet
|
|
David 
      
Beiträge: 27
|
Verfasst: Mo 09.02.04 19:05
Hallo patrick,
das Tutorial ist mir bekannt, es geht aber in eine etwas andere Richtung. Um Threads zu erstellen gibt es schon mehrere Möglichkeiten, diese ist jedoch für meine Situation die Beste.
Ich verstehe nur halt nicht, wieso er beim 2. erstellten Thread abstürtzt und beim 1. nicht.
|
|
MSCH
      
Beiträge: 1448
Erhaltene Danke: 3
W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
|
Verfasst: Mo 09.02.04 19:25
schätze mal, dass deine Initialisierung etwas daneben läuft. Deine Treads laufen erstmal unendlich, rufen unendlich eine Schleife auf und geben eine Dialog aus. Ob diese Funktion Threadsicher ist, wage ich zu bezweifeln und den Thread via :=0 zu terminieren (?) geht auch nicht. Da solltest du schon CloseHandle benutzen. Schau dir mal die Erläuterungen im SDK dazu an.
Das der erste funktioniert, ist Zufall (?).
grez
msch
_________________ ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
|
|
David 
      
Beiträge: 27
|
Verfasst: Mo 09.02.04 19:36
ok, danke Euch beiden. Ich denke, ich bekomme das jetzt hin!
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 09.02.04 20:04
Kennen schon, aber nicht gelesen oder:
| Thread-Tutorial hat folgendes geschrieben: |
Zu beachten ist allerdings noch folgendes: Benutzt man BeginThread als Wrapper für die API-Funktion CreateThread,
so darf man nicht die Aufrufkonvetion stdcall für die Thread-Funktion benutzen. Grund: BeginThread benutzt eine
"Thread-Wrapper"-Funktion anstatt des wirklichen Einsprungspunktes. Diese Funktion ist als stdcall definiert, sie verschiebt
die Parameter auf den Stack und ruft dann die eigene Thread-Funktion auf.
[..]
In einem Delphi-Programm sollten sie nie die Funktion CreateThread direkt aufrufen. Benutzen sie stattdessen die
Funktion BeginThread. Grund: BeginThread kapselt zwar nur die API-Funktion CreateThread, setzt aber zusätzlich
noch die globale Variable IsMultiThread und macht somit den Heap thread-sicher.
|
Die Thread-Funktion sieht auch anders aus:
Delphi-Quelltext 1:
| type TThreadFunc = function(Parameter: Pointer): Integer; |
Aber das eigentliche Problem dürfte die Übergabe des Edits als Thread-Parameter sein. Wie man Parameter an Threads übergibt kannst du in den Demos zu meinem Tutorial sehen. Übergib einen Zeiger auf einen Record.
Und nimm mal statt ShowMessage, Messagebox (die API-Version). Die VCL ist nämlich nicht thread-safe.
Und was deine aukommentierte Edit-Zeile angeht, mach dich mal in meinem Tutorial über CriticalSections schlau.
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mo 09.02.04 20:53
Also was den Parameter betrifft so ist der obige Code durchaus korrekt, schließlich sind in Delphi ja alle Objekte nur Zeiger, also entspricht das übergebene TEdit-Objekt durchaus dem Pointer-Parameter von TThreadFunc. Die Prozeduren sind zwar als stdcall deklariert, aber es sind eben Prozeduren und keine Funktionen wie TThreadFunc (aber das allein ist noch kein schwerwiegendes Problem).
Ich seh das Problem auch bei den VCL-Zugriffen und zwar sowohl bei ShowMessage als auch bei den Zugriffen auf das Edit. Und VCL-Zugriffe würde ich generell sicherheitshalber eher über Synchronize machen als mit CriticalSections, da mit Synchronize der Code im primären Thread ausgeführt wird, während man per CriticalSection zwar seine eigenen Zugriffe auf ein VCL-Control synchronisieren kann, aber was die VCL im Hintergrund macht kann man nicht kontrollieren...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
|