2010-06-12 11 views
6

Ich benutze parallele Erweiterungen ziemlich stark und ich habe gerade einen Fall gefunden, in dem die Verwendung von lokalem Thread-Speicher sinnvoll sein könnte, um die Wiederverwendung von Objekten durch Arbeitsthreads zu ermöglichen. Als solches betrachtete ich das ThreadStatic-Attribut, das ein statisches Feld/eine statische Variable mit einem eindeutigen Wert pro Thread markiert.Verwenden paralleler Erweiterungen mit ThreadStatic-Attribut. Konnte es Speicher verlieren?

Es scheint mir, dass es unklug wäre, PE mit dem ThreadStatic-Attribut zu verwenden, ohne dass die Wiederverwendung von Threads durch PE garantiert wäre. Das heißt, wenn Threads bis zu einem gewissen Grad erstellt und zerstört werden, bleiben die Variablen (und somit die Objekte, auf die sie verweisen) für eine unbestimmte Zeit im lokalen Thread-Speicher und verursachen so ein Speicherleck. Oder vielleicht ist der Fadenspeicher an die Fäden gebunden und entsorgt, wenn die Fäden liegen? Aber dann haben Sie möglicherweise noch Threads in einem Pool, die lange gelebt werden und lokale lokalen Speicher aus verschiedenen Codeteilen ansammeln, für die die Threads verwendet werden.

Gibt es einen besseren Ansatz, lokalen Thread-Speicher mit PE zu erhalten?

Vielen Dank.

+0

Die korrekte Terminologie ist "im Ruhestand" statt "zerstört" in Bezug auf Threads, die aus dem Pool entfernt werden und dann ihre Stacks verschieben. –

Antwort

5

Ich würde dringend empfehlen, das normale Muster für lokalen Thread-Speicher zu verwenden, beschrieben in diesem MSDN article.

Wenn Sie [ThreadStatic] verwenden, ist es wichtig, ob ein Threadpool-Thread die TLS-Variablen beim Beenden bereinigt. In den MSDN-Dokumenten gibt es keinen Vorschlag, dass dies nicht der Fall ist. Es wäre nicht schwer zu implementieren, es muss nur die TlsFree() API-Funktion aufrufen. Ich habe eine kleine Test-App geschrieben, keine Hinweise auf ein Leck.

4

EDIT: Bei Hans Antwort, es klingt wie das TLS tatsächlich würde sowieso gereinigt werden ..., die gerade dieses Stück der Antwort lässt:

Haben Sie wirklich keine bessere Art und Weise Werte der Wiederverwendung innerhalb ein Thread? Wenn es zwei Aufgaben gibt, die den gleichen Thread verwenden (einer beendet, dann die anderen), wollen sie dann wirklich den gleichen Wert haben? Sind Sie eigentlich nur dies als eine Möglichkeit zu vermeiden, die Daten in einer kontrollierten Weise durch Ihre Aufgabe zu verbreiten?

+0

Das Szenario ist eine Simulation einer gitterbasierten "Welt" - unabhängig eine Reihe von Agenten in dieser Welt zu bewerten. Um parallel zu laufen, kann ich also innerhalb jeder Parallelschleife eine neue Welt erschaffen, verwenden und verwerfen. Meine Absicht war, eine Reset() -Methode auf die Welt zu setzen, um eine Wiederverwendung zu ermöglichen. Ich stelle fest, dass der statische lokale Speicher mich davon abhält, meinen eigenen Pool von "Welten" mit zugehörigem thread-locked Zugriff auf den Pool usw. zu verwalten. – redcalx

+0

@ the-locster: Ich fürchte, ich sehe immer noch nicht den Vorteil von thread - Lokaler Speicher hier. Wenn es innerhalb einer Aufgabe ist, warum nicht einfach die Referenz behalten? –

+0

Jede Auswertung versetzt einen Agenten in eine einzige Welt. Wenn ich also 8 CPU-Kerne/Threads habe, kann ich zu jeder Zeit 8 unabhängige Welten simulieren - eine Welt pro Thread. – redcalx