Thread, die 2te
Thread, die 2te
Hi, hier mal ein kurzer Überblick über die Programmstruktur:
Ich erzeuge mehrere Objekte derselben Klasse.
Für jedes erzeugte Objekt wird ein Thread erstellt. (Ein-und dieselbe Funktion für den Thread)
In diesem Thread wird jeweils ein Fenster erstellt und dann das Handle an das Objekt zurückgegeben.
Der Thread läuft die ganze Zeit in einer MsgLoop;
Beim Erstellen des Fensters innerhalb des Threads wurde eine CALLBACK namens WndProc eingetragen.
Wie man auf der Skizze erkennen kann ruft somit jeder der laufenden Threads diese Callback-Funktion auf.
Genau das ist mein Problem. Ich müsste es irgenwie hinbekommen das jeder Thread auch eine Kopie der Callback-Funktion anlegt
und dementsprechend auch ausführt. (So wie es mit der Threadfunktion ja auch geschieht, mehrere laufen parallel unabhängig davon was
die anderen so treiben) Also jeder Thread muss seine eigene Callback haben.
Alternativ würde es reichen wenn ich innerhalb der Callback irgendwie an einen Zeiger des Objects herankomme, die dem Thread angehört der die Callback aufgerufen hat.
Ich habe in einem früheren Programm einmal zusätzliche Daten in einem Fenster gespeichert, weiß aber leider nicht mehr wie das geht.
Damit könnte ich in dem erzeugten Fenster die Addresse des Objekts speichern.
In der Callback hat man ja das Handle des Fensters, dort könnte man dann die Addresse wieder abholen.
Weiß jemand wie das funktioniert oder hat eventuell sogar eine bessere Idee ?
Ich erzeuge mehrere Objekte derselben Klasse.
Für jedes erzeugte Objekt wird ein Thread erstellt. (Ein-und dieselbe Funktion für den Thread)
In diesem Thread wird jeweils ein Fenster erstellt und dann das Handle an das Objekt zurückgegeben.
Der Thread läuft die ganze Zeit in einer MsgLoop;
Beim Erstellen des Fensters innerhalb des Threads wurde eine CALLBACK namens WndProc eingetragen.
Wie man auf der Skizze erkennen kann ruft somit jeder der laufenden Threads diese Callback-Funktion auf.
Genau das ist mein Problem. Ich müsste es irgenwie hinbekommen das jeder Thread auch eine Kopie der Callback-Funktion anlegt
und dementsprechend auch ausführt. (So wie es mit der Threadfunktion ja auch geschieht, mehrere laufen parallel unabhängig davon was
die anderen so treiben) Also jeder Thread muss seine eigene Callback haben.
Alternativ würde es reichen wenn ich innerhalb der Callback irgendwie an einen Zeiger des Objects herankomme, die dem Thread angehört der die Callback aufgerufen hat.
Ich habe in einem früheren Programm einmal zusätzliche Daten in einem Fenster gespeichert, weiß aber leider nicht mehr wie das geht.
Damit könnte ich in dem erzeugten Fenster die Addresse des Objekts speichern.
In der Callback hat man ja das Handle des Fensters, dort könnte man dann die Addresse wieder abholen.
Weiß jemand wie das funktioniert oder hat eventuell sogar eine bessere Idee ?
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Thread, die 2te
Siehe http://zfx.info/viewtopic.php?f=11&t=12 :-)
Damals gab es eine laengere Diskussion ueber die beste Loesung, am Schluss kamen wir bei Thread-Local Storage raus. Jeder Thread speichert den an den Callback zu uebergebenden Pointer in einem TLS-Slot, und der Callback greift dann darauf zu.
Damals gab es eine laengere Diskussion ueber die beste Loesung, am Schluss kamen wir bei Thread-Local Storage raus. Jeder Thread speichert den an den Callback zu uebergebenden Pointer in einem TLS-Slot, und der Callback greift dann darauf zu.
Re: Thread, die 2te
Threadlokale statische Variablen... stimmt, da war doch was *Charles Petzold rauskram*
Danke ^^
Danke ^^
Re: Thread, die 2te
Ok nun hab ich doch mal ne Frage:
Ich hab mir mal das Topic angeschaut und beim Code ist mir aufgefallen:
Nach TlsAlloc() findet nirgends eine Speicherreservierung mit TlsSetValue(GlobalAlloc(GPTR, <Größe des SPeicherbereichs)) auf. [EDIT: eventuell LocalAlloc benutzten]
Es wird direkt ::TlsSetValue(s_tlsIndex, this); ein this pointer im nichts gespeichert.
Sollte man nicht vorher wie unter msdn beschrieben erst den speicher anlegen ?
Auszug aus der MSDN:
When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory in the TLS slot using the TlsSetValue function.
Beispiel: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Ich hab mir mal das Topic angeschaut und beim Code ist mir aufgefallen:
Nach TlsAlloc() findet nirgends eine Speicherreservierung mit TlsSetValue(GlobalAlloc(GPTR, <Größe des SPeicherbereichs)) auf. [EDIT: eventuell LocalAlloc benutzten]
Es wird direkt ::TlsSetValue(s_tlsIndex, this); ein this pointer im nichts gespeichert.
Sollte man nicht vorher wie unter msdn beschrieben erst den speicher anlegen ?
Auszug aus der MSDN:
When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory in the TLS slot using the TlsSetValue function.
Beispiel: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Thread, die 2te
Ein TLS-Slot bietet immer genug Platz fuer einen Pointer. Also kannst du einfach einen this-Pointer drin ablegen, wieder auslesen und auf das referenzierte Objekt zugreifen … wenn du eine grosse rohe Datenmenge in einem TLS-Slot ablegen willst, musst du also tatsaechlich zuerst Speicher anlegen, deine Daten reinschreiben, und den Pointer drauf im TLS ablegen.
Re: Thread, die 2te
Also ist der TLS im Prinzip eine Art "Stack" wie er in "normalen" Anwendungen vorkommt, bei denen man einfach
mit INT *i; etwas anlegen kann ? Also im Prinzip nicht in den Heap schreibt. ( Nur eben mit den kleinen Thread Unterschieden und so...)
mit INT *i; etwas anlegen kann ? Also im Prinzip nicht in den Heap schreibt. ( Nur eben mit den kleinen Thread Unterschieden und so...)
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Thread, die 2te
TLS stellt die Speicher fuer einen Pointer pro Slot zur Verfuegung, den es fuer dich allokiert - fuer das, auf was der Pointer verweist bist du selber verantwortlich. Stell dir TLS als eine Art Inhaltsverzeichnis vor, das jeder Thread mit sich rumschleppt. Wenn du einen Slot nachschlaegst, kriegst du nur die Seitennummer.
Re: Thread, die 2te
Entschuldige, aber ich hab noch eine letzte Frage bevor mir alles klar wird:
Wenn TLS Speicher für einen Pointer breitstellt...
kann ich doch trotzdem mit
mehr Speicher im TLS einfordern, oder ?
Dh. ich kann dann ganze Strukturen und Klassen hineinpacken anstatt nur den Pointer drauf.
Stimmt das so ?
Wenn TLS Speicher für einen Pointer breitstellt...
kann ich doch trotzdem mit
Code: Alles auswählen
TlsSetValue(dwTlsIndex, GlobalAlloc(GPTR, <GRÖßE DES SPEICHERS>));
Dh. ich kann dann ganze Strukturen und Klassen hineinpacken anstatt nur den Pointer drauf.
Stimmt das so ?
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Thread, die 2te
Nein, in deinem Beispiel legst du einen neuen Speicherbereich an und legst den Pointer drauf im TLS ab -- der Platz im TLS wird dadurch nicht vergrössert, aber über diesen Pointer kriegt dein Thread so viel privaten Speicher wie du eben angelegt hast.
Grundsätzlich liegst du schon richtig, nur speichert das TLS immer noch nur einen Pointer pro Slot :-)
Grundsätzlich liegst du schon richtig, nur speichert das TLS immer noch nur einen Pointer pro Slot :-)
Re: Thread, die 2te
Vielen Dank, ich habs endlich verstanden :)
Der "return value" Teil von GlobalAlloc in der MSDN erklärt auch einiges... naja hinterher ist man immer schlauer ^^
Hab übrigens jetzt alles Implementiert, alle Threads funkionieren einwandfrei.
Dass ich das noch mal erleben darf *freu*
SkyNet ich komme ^^ (Wer Terminator kennt ahnt vielleicht was es wird ;) )
Der "return value" Teil von GlobalAlloc in der MSDN erklärt auch einiges... naja hinterher ist man immer schlauer ^^
Hab übrigens jetzt alles Implementiert, alle Threads funkionieren einwandfrei.
Dass ich das noch mal erleben darf *freu*
SkyNet ich komme ^^ (Wer Terminator kennt ahnt vielleicht was es wird ;) )