it-swarm.com.de

Haben Threads einen deutlichen Haufen?

Soweit ich weiß, erhält jeder Thread einen eigenen Stapel, wenn der Thread vom Betriebssystem erstellt wird. Ich frage mich, ob jeder Thread auch einen eigenen Haufen hat.

110
user188276

Nein. Alle Threads teilen sich einen gemeinsamen Haufen.

Jeder Thread hat einen privaten Stack , mit dem er schnell Elemente hinzufügen und daraus entfernen kann. Dies macht stapelbasierten Speicher schnell, aber wenn Sie zu viel Stapelspeicher verwenden, wie dies bei unendlicher Rekursion der Fall ist, kommt es zu einem Stapelüberlauf.

Da sich alle Threads den gleichen Heap teilen, muss der Zugriff auf den Allokator/Deallocator synchronisiert werden. Es gibt verschiedene Methoden und Bibliotheken, um Zuweisungskonflikt zu vermeiden.

In einigen Sprachen können Sie private Speicherpools oder einzelne Heaps erstellen, die Sie einem einzelnen Thread zuweisen können.

121
brianegge

Standardmäßig verfügt C nur über einen einzelnen Heap.

Das heißt, einige Thread-fähige Allokatoren partitionieren den Heap, sodass jeder Thread seinen eigenen Bereich hat, aus dem er allokieren kann. Die Idee ist, dass dies die Heap-Skalierung verbessern soll.

Ein Beispiel für einen solchen Haufen ist Hort .

9

Kommt auf das Betriebssystem an. Die Standard-C-Laufzeit unter Windows und Unices verwendet einen geteilten Heap über Threads hinweg. Dies bedeutet, dass jeder Malloc/Free gesperrt wird.

Unter Symbian verfügt beispielsweise jeder Thread über einen eigenen Heap, obwohl Threads Zeiger auf in jedem Heap zugewiesene Daten gemeinsam nutzen können. Das Design von Symbian ist meiner Meinung nach besser, da es nicht nur das Sperren während der Zuweisung/Freigabe überflüssig macht, sondern auch eine saubere Spezifikation des Datenbesitzes zwischen Threads fördert. Auch in diesem Fall, wenn ein Thread stirbt, nimmt er alle ihm zugewiesenen Objekte mit - d. H. Er kann keine von ihm zugewiesenen Objekte verlieren, was eine wichtige Eigenschaft bei mobilen Geräten mit eingeschränktem Speicher ist.

Erlang folgt auch einem ähnlichen Entwurf, bei dem ein "Prozess" als Einheit der Speicherbereinigung fungiert. Alle Daten werden durch Kopieren zwischen Prozessen übertragen, mit Ausnahme von binären Blobs, die referenziert sind (glaube ich).

5
Srikumar

Jeder Thread verfügt über einen eigenen Stapel und einen Aufrufstapel.

Jeder Thread teilt sich den gleichen Heap.

3
tsalter

Es kommt darauf an, was genau Sie meinen, wenn Sie "Haufen" sagen.

Alle Threads teilen sich den Adressraum, sodass von allen Threads aus auf von Heap zugewiesene Objekte zugegriffen werden kann. Technisch gesehen werden Stapel auch in diesem Sinne gemeinsam genutzt, d. H. Nichts hindert Sie daran, auf den Stapel anderer Threads zuzugreifen (obwohl dies so gut wie nie sinnvoll wäre).

Auf der anderen Seite gibt es Heap -Strukturen , die zum Zuweisen von Speicher verwendet werden. Hier wird die gesamte Buchhaltung für die Heapspeicherzuweisung durchgeführt. Diese Strukturen sind durchdacht organisiert, um Konflikte zwischen den Threads zu minimieren. Einige Threads teilen sich daher möglicherweise eine Heap-Struktur (eine Arena), andere verwenden möglicherweise unterschiedliche Arenen.
Im folgenden Thread finden Sie eine hervorragende Erklärung der Details: Wie funktioniert malloc in einer Multithread-Umgebung?

2
VladV

Im Allgemeinen verwenden alle Threads denselben Adressraum und haben daher normalerweise nur einen Heap.

Es kann jedoch etwas komplizierter sein. Möglicherweise suchen Sie nach Thread Local Storage (TLS), aber es werden nur einzelne Werte gespeichert.

Windows-spezifisch: TLS-Speicherplatz kann mit TlsAlloc zugewiesen und mit TlsFree freigegeben werden (Übersicht hier ). Wieder ist es kein Haufen, nur DWORDs.

Seltsamerweise unterstützt Windows mehrere Heaps pro Prozess. Das Handle des Heaps kann in TLS gespeichert werden. Dann hätten Sie so etwas wie einen "Thread-Local Heap". Nur das Handle ist den anderen Threads jedoch nicht bekannt. Sie können weiterhin mithilfe von Zeigern auf den Speicher zugreifen, da es sich immer noch um denselben Adressraum handelt.

[~ # ~] edit [~ # ~] : Einige Speicherzuweiser (speziell jemalloc unter FreeBSD) verwenden TLS zum Zuweisen "Arenen" zu Threads. Auf diese Weise wird die Zuordnung für mehrere Kerne optimiert, indem der Synchronisationsaufwand verringert wird.

1
Meinersbur

In der Regel teilen sich Threads den Heap und andere Ressourcen, jedoch gibt es threadähnliche Konstruktionen, die dies nicht tun. Zu diesen threadähnlichen Konstruktionen gehören die Lightweight-Prozesse von Erlang und die Full-On-Prozesse von UNIX (die mit einem Aufruf von fork() erstellt wurden). Möglicherweise arbeiten Sie auch an der Parallelität mehrerer Computer. In diesem Fall sind die Kommunikationsoptionen zwischen Threads erheblich eingeschränkter.

1
Ken Bloom

Auf dem FreeRTOS-Betriebssystem teilen sich Aufgaben (Threads) denselben Heap, aber jeder von ihnen hat seinen eigenen Stack. Dies ist sehr praktisch, wenn Sie mit Architekturen mit niedrigem Stromverbrauch RAM arbeiten, da mehrere Threads auf denselben Speicherpool zugreifen/ihn gemeinsam nutzen können. Dies birgt jedoch einen kleinen Haken, den der Entwickler beachten muss: a Es wird ein Mechanismus zum Synchronisieren von malloc und free benötigt. Aus diesem Grund ist es erforderlich, eine Art von Prozesssynchronisierung/-sperre zu verwenden, um Speicher auf dem Heap zuzuweisen oder freizugeben, z. B. ein Semaphor oder ein Mutex.

1