Thread, die 2te

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Thread, die 2te

Beitrag von Neo.uc »

Hi, hier mal ein kurzer Überblick über die Programmstruktur:
Bild

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 ?
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Aramis »

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.
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Neo.uc »

Threadlokale statische Variablen... stimmt, da war doch was *Charles Petzold rauskram*
Danke ^^
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Neo.uc »

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
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Aramis »

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.
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Neo.uc »

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...)
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Aramis »

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.
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Neo.uc »

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

Code: Alles auswählen

TlsSetValue(dwTlsIndex, GlobalAlloc(GPTR, <GRÖßE DES SPEICHERS>));
mehr Speicher im TLS einfordern, oder ?
Dh. ich kann dann ganze Strukturen und Klassen hineinpacken anstatt nur den Pointer drauf.

Stimmt das so ?
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Aramis »

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 :-)
Neo.uc
Beiträge: 19
Registriert: 17.04.2003, 16:31
Kontaktdaten:

Re: Thread, die 2te

Beitrag von Neo.uc »

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 ;) )
Antworten