AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Thread-Parameter auf dem Stack übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

Thread-Parameter auf dem Stack übergeben

Ein Thema von Luckie · begonnen am 12. Mär 2008 · letzter Beitrag vom 12. Mär 2008
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 08:52
Ich kann einem Thread Parameter entweder über den Heap oder über den Stack mitgeben. Übergebe ich sie über den Heap, muss ich Speicher reservieren und im Thread natürlich wieder freigeben.

Aber wie funktioniert das, wenn ich die Parameter über den Stack übergebe? Siehe dazu das Beispiel. Wer gibt da wann und wie den Speicher wieder frei?

Delphi-Quellcode:
type
  TThreadParams = packed record
    Number: Integer;
    Text: String;
  end;
  PThreadParams = ^TThreadParams;

function IntToStr(Int: integer): string;
begin
  Str(Int, result);
end;

function ThreadFunc(tp: PThreadParams): Integer;
var
  Number: Integer;
  Text: String;
  s: String;
begin
  Number := PThreadParams(tp)^.Number;
  Text := PThreadParams(tp)^.Text;
  s := 'Zahl: ' + IntToStr(Number) + #13#10 + 'Text: ' + Text;
  Result := MessageBox(0, PChar(s), 'Thread', MB_YESNO or MB_ICONINFORMATION);
end;

var
  tp: TThreadParams;
  Thread: THandle;
  ThreadID: Cardinal;
  ExitCode: Cardinal;

begin
  tp.Number := 42;
  tp.Text := 'Die Antwort.';
  Thread := BeginThread(nil, 0, @ThreadFunc, @tp, 0, ThreadID);
  WaitForSingleObject(Thread, INFINITE);
  GetExitCodeThread(Thread, ExitCode);
  case ExitCode of
    IDYES: Writeln('Benutrzer hat "Ja" angeklickt.');
    IDNO: Writeln('Benutzer hat "Nein" angeklickt.');
  end;
  CloseHandle(Thread);
  Readln;
end.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: TRhread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:00
Das wird so nicht gehen. Du musst dafür sorgen, dass die Parameter auf dem Stack nicht überschrieben werden, während der Thread darauf zugreift - was im schlimmsten Fall über die gesamte Threadlaufzeit geschieht. Für diese Zeit musst du auf den Thread warten, da ein Return aus der aktuellen Methode dafür Sorgen würde, dass dein Parameter Freiwild wird und vom nächsten Aufruf im erzeugenden Thread höchstwahrscheinlich gründlich zerlegt wird. Was natürlich bedeuten würde, dass Threads in dem Fall eher.. naja, sinnlos sind.

Aber zum eigentlich Thema: den Speicher freigeben muss der Aufrufer, wenn es der Thread nicht tut. Da du den Speicher über den Stack holst, musst du ihn *garnicht* freigeben, du darfst es sogar nicht mal, nicht im Thread und nirgendwo sonst, das macht nämlich deine Methode automatisch beim Return.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:03
Derzeit übergibst du eine globale Variable.
Solange du im Mainthread die golabel Variable nicht änderst (was du ja auf Grund von WaitForsingleObject ja erriechst) kein Problem.
Wenn du den Parameter wirklich auf dem Stack hast (loakle Variable) wird diese spätestens nach Abschluss der Prozedur ungültig.

Also nur Heap benutzen!
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:05
Dass es ohne warten nicht funktionieren würde ist klar, aber das tue ich ja in meinem Fall. Und was das Freigeben angeht, der Speicher auf dem Stack wird beim Verlassen der Funktion automatisch vom Betriebssystem aufgeräumt. Habe ich das so richtig verstanden?

@sirius: Stimmt, hier ist sie ja global, also auf dem Heap. Dann muss ich das noch mal umbauen.

So sollte es eigentlich sein:

Delphi-Quellcode:
function ThreadFunc(tp: PThreadParams): Integer;
var
  Number: Integer;
  Text: String;
  s: String;
begin
  Number := PThreadParams(tp)^.Number;
  Text := PThreadParams(tp)^.Text;
  s := 'Zahl: ' + IntToStr(Number) + #13#10 + 'Text: ' + Text;
  Result := MessageBox(0, PChar(s), 'Thread', MB_YESNO or MB_ICONINFORMATION);
end;

procedure RunThread;
var
  tp: TThreadParams;
  Thread: THandle;
  ThreadID: Cardinal;
  ExitCode: Cardinal;
begin
  tp.Number := 42;
  tp.Text := 'Die Antwort.';
  Thread := BeginThread(nil, 0, @ThreadFunc, @tp, 0, ThreadID);
  WaitForSingleObject(Thread, INFINITE);
  GetExitCodeThread(Thread, ExitCode);
  case ExitCode of
    IDYES: Writeln('Benutrzer hat "Ja" angeklickt.');
    IDNO: Writeln('Benutzer hat "Nein" angeklickt.');
  end;
  CloseHandle(Thread);
end;
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:07
du übergibst den Parameter ja gar nicht über den Stack. Da es eine globale Variable ist liegt diese nicht auf dem Stack. Aber selbst wenn sie auf dem Stack liegen würde übergibst du sie nicht über den Stack sondern du übergibst ja dem Thread generell nur einen Pointer auf Daten die irgendwo liegen. Und du musst nur dafür sorgen das die Daten worauf der Pointer zeigt auch noch da sind wenn über den Pointer darauf zugegriffen wird.

Dadurch das du auf den thread wartest bis er beendet ist würde der Inhalt auf dem Stack auch unverändert bleiben.

Der Stack wird übrigens nicht vom Betriebssystem aufgeräumt. Je nach Calling Convention wird der Stack dort aufgeräumt wo die Funktion aufgerufen wurde oder eben in der Funktion. Wenn du dir den asm-code ansiehst wirst du sehen das explizit funktionen aufgerufen werden die den Stack auf- und abbauen.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#6

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:13
Zitat von Luckie:
Und was das Freigeben angeht, der Speicher auf dem Stack wird beim Verlassen der Funktion automatisch vom Betriebssystem aufgeräumt. Habe ich das so richtig verstanden?
Nein. Das Betriebssystem hat damit recht wenig zu tun, der von der Methode belegte Stackspeicher wird von der Methode selbst beim Return wieder an den Stack zurückgegeben.

Ein kleines Beispiel dazu:

-Eintritt in die Methode: SP steht auf 1000
-Methode schnapp sich 100 Byte Stackspeicher: SP auf 1100
-Method gedönst rum...
-Method gibt Stackspeicher frei: SP wieder auf 1000
-ret: SP auf 996 (für 32er-Systeme)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:15
Ich habe das Beispiel geändert. Jetzt liegt der Thread-Parameter auf dem Stack. Damit dass das Betriebssystem den Stack aufräumt, hab eich mich wohl etwas ungenau ausgedrückt. Ich wollte damit ausdrücken, dass dies automatisch geschieht ohne dass man als zusätzlichen, eigenen Code dafür schreiben müsste, wie man es muss, wenn man den Parameter über den Heap übergibt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:16
bischen Krümelkacken: Der stackpointer läuft rückwärts, wird also von oben nach unten gefüllt. Pack man was auf den Stack drauf wird der Stackpointer decrementiert (zeigt also auf eine niederigere Adresse als vorher)
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:16
Zitat von Luckie:
@sirius: Stimmt, hier ist sie ja global, also auf dem Heap. Dann muss ich das noch mal umbauen.
Nee globale (nicht dynamische) Varibalen sind nicht auf dem Heap. sie sind schon Teil der EXE und werden so im Datensegment mit reingeladen.

Und als Ergänzung noch zu Dax:
Auf Grund von Codeoptimierung kann es passieren, dass die Gültigkeit schon vor Ablauf der Funktion aufgehoben wird und der Stackplatz von einer anderen lokalen Variable belegt wird.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Thread-Parameter auf dem Stack übergeben

  Alt 12. Mär 2008, 09:19
@sirius: Die Codeoptimierung sollte aber auch berücksichtigen das ein Pointer auf die lokale Variable verwendet wurde und somit die Gültigkeit länger anhält. In Sprachen wie C gibt es dafür volatile um das weg optimieren zu verhindern (zum Beispiel für so einen Fall wenn ein anderer Thread noch darauf zugreifen könnte). In Delphi ist mir diesbezüglich nichts bekannt.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:23 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